package com.tzkyzj.tiremanager.service;

import com.tzkyzj.tiremanager.dto.*;
import com.tzkyzj.tiremanager.entity.*;
import com.tzkyzj.tiremanager.repository.SettlementRecordRepository;
import com.tzkyzj.tiremanager.repository.TirePhotoRepository;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;
import com.tzkyzj.tiremanager.repository.TireRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

@Service
public class TireService {

    private static final Logger log = LoggerFactory.getLogger(TireService.class);

    @Autowired
    private SettlementRecordRepository settlementRecordRepository;

    @Autowired
    private TirePhotoRepository tirePhotoRepository;

    @Autowired
    private TirePhotoService tirePhotoService; // 添加这行

    @Value("${app.upload.path:uploads}")
    private String uploadPath;






    /**
     * 获取轮胎的所有照片
     */
    public List<TirePhoto> getPhotosByTireId(Long tireId) {
        return tirePhotoRepository.findByTireId(tireId);
    }

    /**
     * 获取单个照片
     */
    public Optional<TirePhoto> getPhoto(Long tireId, Long photoId) {
        return tirePhotoRepository.findByIdAndTireId(photoId, tireId);
    }

    /**
     * 删除照片
     */
    public void deletePhoto(Long tireId, Long photoId) throws IOException {
        Optional<TirePhoto> photoOpt = tirePhotoRepository.findByIdAndTireId(photoId, tireId);
        if (photoOpt.isPresent()) {
            TirePhoto photo = photoOpt.get();

            // 删除文件
            Path filePath = Paths.get(photo.getFilePath());
            if (Files.exists(filePath)) {
                Files.delete(filePath);
            }

            // 删除数据库记录
            tirePhotoRepository.delete(photo);
        }
    }





    public List<SettlementRecord> getLatestSettlementRecords(int limit) {
        try {
            log.info("获取最新 {} 条结算记录", limit);

            // 使用 JPA 的分页查询
            Pageable pageable = PageRequest.of(0, limit, Sort.by(Sort.Direction.DESC, "settlementDate"));
            return settlementRecordRepository.findAllByOrderBySettlementDateDesc(pageable);

        } catch (Exception e) {
            log.error("获取最新结算记录失败", e);
            // 降级方案：获取所有记录后手动排序和限制
            List<SettlementRecord> allRecords = settlementRecordRepository.findAll();
            allRecords.sort((r1, r2) -> {
                if (r1.getSettlementDate() == null && r2.getSettlementDate() == null) return 0;
                if (r1.getSettlementDate() == null) return 1;
                if (r2.getSettlementDate() == null) return -1;
                return r2.getSettlementDate().compareTo(r1.getSettlementDate());
            });

            if (allRecords.size() > limit) {
                return allRecords.subList(0, limit);
            }
            return allRecords;
        }
    }

    /**
     * 获取结算记录的车牌号自动补全列表
     */
    public List<String> getSettlementPlateNumberSuggestions(String keyword) {
        return settlementRecordRepository.findDistinctPlateNumbers(keyword);
    }

    /**
     * 根据条件搜索结算记录
     */
    public List<SettlementRecord> searchSettlementRecords(String plateNumber, String transportCompany,
                                                          LocalDate startDate, LocalDate endDate) {
        if (StringUtils.hasText(plateNumber)) {
            return settlementRecordRepository.findByPlateNumberContainingIgnoreCase(plateNumber);
        } else if (StringUtils.hasText(transportCompany)) {
            return settlementRecordRepository.findByTransportCompany(transportCompany);
        } else if (startDate != null && endDate != null) {
            return settlementRecordRepository.findBySettlementDateBetween(startDate, endDate);
        } else {
            return settlementRecordRepository.findAllOrderByCreateTimeDesc();
        }
    }

    /**
     * 生成结算单号
     */
    private String generateInvoiceNumber() {
        String timestamp = String.valueOf(System.currentTimeMillis());
        String random = String.valueOf((int)(Math.random() * 1000));
        return "INV" + timestamp + random;
    }

    /**
     * 获取结算记录统计信息
     */
    public Map<String, Object> getSettlementStatistics(LocalDate startDate, LocalDate endDate) {
        List<SettlementRecord> records;

        if (startDate != null && endDate != null) {
            records = settlementRecordRepository.findBySettlementDateBetween(startDate, endDate);
        } else {
            records = settlementRecordRepository.findAll();
        }

        Map<String, Object> statistics = new HashMap<>();

        // 总记录数
        statistics.put("totalRecords", records.size());

        // 总金额
        double totalAmount = records.stream()
                .mapToDouble(SettlementRecord::getTotalCost)
                .sum();
        statistics.put("totalAmount", totalAmount);

        // 按服务类型统计
        Map<String, Double> serviceTypeStats = new HashMap<>();
        for (SettlementRecord record : records) {
            if (record.getItems() != null) {
                for (SettlementItem item : record.getItems()) {
                    String serviceType = item.getServiceType();
                    double amount = (item.getTireCost() != null ? item.getTireCost() : 0) +
                            (item.getServiceCost() != null ? item.getServiceCost() : 0);
                    serviceTypeStats.merge(serviceType, amount, Double::sum);
                }
            }
        }
        statistics.put("serviceTypeStats", serviceTypeStats);

        // 按运输公司统计
        Map<String, Double> companyStats = new HashMap<>();
        for (SettlementRecord record : records) {
            String company = record.getTransportCompany();
            if (company == null) {
                company = "未知公司";
            }
            companyStats.merge(company, record.getTotalCost(), Double::sum);
        }
        statistics.put("companyStats", companyStats);

        return statistics;
    }





    /**
     * 保存结算记录
     */
    @Transactional
    public SettlementRecord saveSettlementRecord(SettlementRecord settlementRecord) {
        // 设置关联关系
        if (settlementRecord.getItems() != null) {
            for (SettlementItem item : settlementRecord.getItems()) {
                item.setSettlementRecord(settlementRecord);
            }
        }

        // 计算总费用
        Double totalCost = calculateTotalCost(settlementRecord);
        settlementRecord.setTotalCost(totalCost);

        return settlementRecordRepository.save(settlementRecord);
    }

    /**
     * 计算总费用
     */
    private Double calculateTotalCost(SettlementRecord settlementRecord) {
        if (settlementRecord.getItems() == null) {
            return 0.0;
        }

        return settlementRecord.getItems().stream()
                .mapToDouble(item -> (item.getTireCost() != null ? item.getTireCost() : 0) +
                        (item.getServiceCost() != null ? item.getServiceCost() : 0))
                .sum();
    }

    /**
     * 获取所有结算记录
     */
    public List<SettlementRecord> getAllSettlementRecords() {
        return settlementRecordRepository.findAllOrderByCreateTimeDesc();
    }

    /**
     * 根据ID获取结算记录
     */
    public SettlementRecord getSettlementRecordById(Long id) {
        return settlementRecordRepository.findById(id).orElse(null);
    }

    /**
     * 根据车牌号搜索结算记录
     */
    public List<SettlementRecord> searchByPlateNumber(String plateNumber) {
        return settlementRecordRepository.findByPlateNumberContainingIgnoreCase(plateNumber);
    }

    /**
     * 根据运输公司搜索结算记录
     */
    public List<SettlementRecord> searchByTransportCompany(String company) {
        return settlementRecordRepository.findByTransportCompany(company);
    }

    /**
     * 根据日期范围搜索结算记录
     */
    public List<SettlementRecord> searchByDateRange(LocalDate startDate, LocalDate endDate) {
        return settlementRecordRepository.findBySettlementDateBetween(startDate, endDate);
    }

    /**
     * 获取车牌号自动补全列表
     */
    public List<String> getPlateNumberSuggestions(String keyword) {
        return settlementRecordRepository.findDistinctPlateNumbers(keyword);
    }

    /**
     * 获取费用统计
     */
    public Map<String, Object> getCostStatistics(LocalDate startDate, LocalDate endDate, String company) {
        List<SettlementRecord> records;

        if (startDate != null && endDate != null) {
            records = searchByDateRange(startDate, endDate);
        } else if (company != null && !company.isEmpty()) {
            records = searchByTransportCompany(company);
        } else {
            records = getAllSettlementRecords();
        }

        Map<String, Object> statistics = new HashMap<>();

        // 计算各类费用
        Double totalCost = records.stream()
                .mapToDouble(SettlementRecord::getTotalCost)
                .sum();

        Double repairCost = records.stream()
                .flatMap(record -> record.getItems().stream())
                .filter(item -> "repair".equals(item.getServiceType()))
                .mapToDouble(SettlementItem::getSubtotal)
                .sum();

        Double installCost = records.stream()
                .flatMap(record -> record.getItems().stream())
                .filter(item -> "install".equals(item.getServiceType()))
                .mapToDouble(SettlementItem::getSubtotal)
                .sum();

        Double replaceCost = records.stream()
                .flatMap(record -> record.getItems().stream())
                .filter(item -> "replace".equals(item.getServiceType()))
                .mapToDouble(SettlementItem::getSubtotal)
                .sum();

        statistics.put("totalCost", totalCost);
        statistics.put("repairCost", repairCost);
        statistics.put("installCost", installCost);
        statistics.put("replaceCost", replaceCost);
        statistics.put("recordCount", records.size());

        return statistics;
    }






    /**
     * 获取费用统计数据
     */
    public CostStatisticsResponse getCostStatistics(String company, Integer year, Integer month, String statType, int page, int size) {
        log.info("获取费用统计: company={}, year={}, month={}, statType={}, page={}, size={}",
                company, year, month, statType, page, size);

        CostStatisticsResponse response = new CostStatisticsResponse();

        try {
            // 1. 获取费用汇总数据
            CostSummary summary = calculateCostSummary(company, year, month, statType);
            response.setSummary(summary);

            // 2. 获取图表数据 - 从数据库获取真实数据
            ChartData chartData = buildChartDataFromDatabase(company, year, month, statType);
            response.setChartData(chartData);

            // 3. 获取费用明细
            List<CostDetail> details = getCostDetails(company, year, month, statType, page, size);
            response.setDetails(details);

            // 4. 添加分页信息
            PaginationInfo pagination = new PaginationInfo();
            pagination.setCurrentPage(page);
            pagination.setPageSize(size);
            pagination.setTotalRecords(details.size()); // 这里应该是总记录数，需要从查询中获取
            pagination.setTotalPages((int) Math.ceil((double) details.size() / size));
            response.setPagination(pagination);

        } catch (Exception e) {
            log.error("获取费用统计数据失败", e);
            // 返回空数据而不是抛出异常，避免前端显示错误
            response.setSummary(new CostSummary());
            response.setChartData(new ChartData());
            response.setDetails(new ArrayList<>());
            response.setPagination(new PaginationInfo());
        }

        return response;
    }

    /**
     * 从数据库构建图表数据
     */
    private ChartData buildChartDataFromDatabase(String company, Integer year, Integer month, String statType) {
        ChartData chartData = new ChartData();

        try {
            // 获取符合条件的轮胎数据
            List<Tire> tires = getTiresForCostStatistics(company, year, month, statType);

            if ("vehicle".equals(statType)) {
                // 单车结算 - 按车牌号分组统计
                buildVehicleChartData(chartData, tires);
            } else if ("company".equals(statType)) {
                // 公司统计 - 按运输公司分组统计
                buildCompanyChartData(chartData, tires);
            } else if ("yearly".equals(statType)) {
                // 年度统计 - 按月份统计
                buildYearlyChartData(chartData, tires, year);
            } else {
                // 月度统计 - 默认按最近6个月统计
                buildMonthlyChartData(chartData, tires);
            }

        } catch (Exception e) {
            log.error("从数据库构建图表数据失败", e);
            // 设置默认值
            chartData.setLabels(Arrays.asList("1月", "2月", "3月", "4月", "5月", "6月"));
            chartData.setPurchaseData(Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
            chartData.setRepairData(Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
            chartData.setOtherData(Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
        }

        return chartData;
    }

    /**
     * 构建单车结算图表数据 - 按车牌号分组
     */
    private void buildVehicleChartData(ChartData chartData, List<Tire> tires) {
        // 按车牌号分组统计费用
        Map<String, VehicleCost> vehicleCostMap = new HashMap<>();

        for (Tire tire : tires) {
            String plateNumber = getDisplayPlateNumber(tire);
            VehicleCost cost = vehicleCostMap.getOrDefault(plateNumber, new VehicleCost());

            // 累加采购费用
            if (tire.getTirePrice() != null) {
                cost.setPurchaseCost(cost.getPurchaseCost() + tire.getTirePrice().doubleValue());
            }

            // 累加维修费用
            if (tire.getRepairCost() != null) {
                cost.setRepairCost(cost.getRepairCost() + tire.getRepairCost().doubleValue());
            }

            // 累加其他费用
            double otherCost = 0.0;
            if (tire.getInstallCost() != null) {
                otherCost += tire.getInstallCost().doubleValue();
            }
            if (tire.getSwapCost() != null) {
                otherCost += tire.getSwapCost().doubleValue();
            }
            cost.setOtherCost(cost.getOtherCost() + otherCost);

            vehicleCostMap.put(plateNumber, cost);
        }

        // 构建图表数据
        List<String> labels = new ArrayList<>();
        List<Double> purchaseData = new ArrayList<>();
        List<Double> repairData = new ArrayList<>();
        List<Double> otherData = new ArrayList<>();

        for (Map.Entry<String, VehicleCost> entry : vehicleCostMap.entrySet()) {
            labels.add(entry.getKey());
            VehicleCost cost = entry.getValue();
            purchaseData.add(round(cost.getPurchaseCost()));
            repairData.add(round(cost.getRepairCost()));
            otherData.add(round(cost.getOtherCost()));
        }

        chartData.setLabels(labels);
        chartData.setPurchaseData(purchaseData);
        chartData.setRepairData(repairData);
        chartData.setOtherData(otherData);
    }

    /**
     * 构建公司统计图表数据 - 按运输公司分组
     */
    private void buildCompanyChartData(ChartData chartData, List<Tire> tires) {
        // 按运输公司分组统计费用
        Map<String, CompanyCost> companyCostMap = new HashMap<>();

        for (Tire tire : tires) {
            String company = tire.getTransportCompany();
            if (company == null) {
                company = "未知公司";
            }

            CompanyCost cost = companyCostMap.getOrDefault(company, new CompanyCost());

            // 累加采购费用
            if (tire.getTirePrice() != null) {
                cost.setPurchaseCost(cost.getPurchaseCost() + tire.getTirePrice().doubleValue());
            }

            // 累加维修费用
            if (tire.getRepairCost() != null) {
                cost.setRepairCost(cost.getRepairCost() + tire.getRepairCost().doubleValue());
            }

            // 累加其他费用
            double otherCost = 0.0;
            if (tire.getInstallCost() != null) {
                otherCost += tire.getInstallCost().doubleValue();
            }
            if (tire.getSwapCost() != null) {
                otherCost += tire.getSwapCost().doubleValue();
            }
            cost.setOtherCost(cost.getOtherCost() + otherCost);

            companyCostMap.put(company, cost);
        }

        // 构建图表数据
        List<String> labels = new ArrayList<>();
        List<Double> purchaseData = new ArrayList<>();
        List<Double> repairData = new ArrayList<>();
        List<Double> otherData = new ArrayList<>();

        for (Map.Entry<String, CompanyCost> entry : companyCostMap.entrySet()) {
            labels.add(entry.getKey());
            CompanyCost cost = entry.getValue();
            purchaseData.add(round(cost.getPurchaseCost()));
            repairData.add(round(cost.getRepairCost()));
            otherData.add(round(cost.getOtherCost()));
        }

        chartData.setLabels(labels);
        chartData.setPurchaseData(purchaseData);
        chartData.setRepairData(repairData);
        chartData.setOtherData(otherData);
    }

    /**
     * 构建年度统计图表数据 - 按月份统计
     */
    private void buildYearlyChartData(ChartData chartData, List<Tire> tires, Integer year) {
        // 按月份分组统计费用
        Map<Integer, MonthlyCost> monthlyCostMap = new HashMap<>();

        // 初始化12个月
        for (int i = 1; i <= 12; i++) {
            monthlyCostMap.put(i, new MonthlyCost());
        }

        for (Tire tire : tires) {
            LocalDate installDate = tire.getInstallDate();
            if (installDate != null) {
                int month = installDate.getMonthValue();
                MonthlyCost cost = monthlyCostMap.get(month);

                // 累加采购费用
                if (tire.getTirePrice() != null) {
                    cost.setPurchaseCost(cost.getPurchaseCost() + tire.getTirePrice().doubleValue());
                }

                // 累加维修费用
                if (tire.getRepairCost() != null) {
                    cost.setRepairCost(cost.getRepairCost() + tire.getRepairCost().doubleValue());
                }

                // 累加其他费用
                double otherCost = 0.0;
                if (tire.getInstallCost() != null) {
                    otherCost += tire.getInstallCost().doubleValue();
                }
                if (tire.getSwapCost() != null) {
                    otherCost += tire.getSwapCost().doubleValue();
                }
                cost.setOtherCost(cost.getOtherCost() + otherCost);
            }
        }

        // 构建图表数据
        List<String> labels = Arrays.asList("1月", "2月", "3月", "4月", "5月", "6月",
                "7月", "8月", "9月", "10月", "11月", "12月");
        List<Double> purchaseData = new ArrayList<>();
        List<Double> repairData = new ArrayList<>();
        List<Double> otherData = new ArrayList<>();

        for (int i = 1; i <= 12; i++) {
            MonthlyCost cost = monthlyCostMap.get(i);
            purchaseData.add(round(cost.getPurchaseCost()));
            repairData.add(round(cost.getRepairCost()));
            otherData.add(round(cost.getOtherCost()));
        }

        chartData.setLabels(labels);
        chartData.setPurchaseData(purchaseData);
        chartData.setRepairData(repairData);
        chartData.setOtherData(otherData);
    }

    /**
     * 构建月度统计图表数据 - 按最近6个月统计
     */
    private void buildMonthlyChartData(ChartData chartData, List<Tire> tires) {
        // 获取最近6个月
        List<String> recentMonths = getRecentMonths(6);
        Map<String, MonthlyCost> monthlyCostMap = new HashMap<>();

        // 初始化最近6个月
        for (String month : recentMonths) {
            monthlyCostMap.put(month, new MonthlyCost());
        }

        for (Tire tire : tires) {
            LocalDate installDate = tire.getInstallDate();
            if (installDate != null) {
                String monthKey = installDate.getMonthValue() + "月";
                if (monthlyCostMap.containsKey(monthKey)) {
                    MonthlyCost cost = monthlyCostMap.get(monthKey);

                    // 累加采购费用
                    if (tire.getTirePrice() != null) {
                        cost.setPurchaseCost(cost.getPurchaseCost() + tire.getTirePrice().doubleValue());
                    }

                    // 累加维修费用
                    if (tire.getRepairCost() != null) {
                        cost.setRepairCost(cost.getRepairCost() + tire.getRepairCost().doubleValue());
                    }

                    // 累加其他费用
                    double otherCost = 0.0;
                    if (tire.getInstallCost() != null) {
                        otherCost += tire.getInstallCost().doubleValue();
                    }
                    if (tire.getSwapCost() != null) {
                        otherCost += tire.getSwapCost().doubleValue();
                    }
                    cost.setOtherCost(cost.getOtherCost() + otherCost);
                }
            }
        }

        // 构建图表数据
        List<Double> purchaseData = new ArrayList<>();
        List<Double> repairData = new ArrayList<>();
        List<Double> otherData = new ArrayList<>();

        for (String month : recentMonths) {
            MonthlyCost cost = monthlyCostMap.get(month);
            purchaseData.add(round(cost.getPurchaseCost()));
            repairData.add(round(cost.getRepairCost()));
            otherData.add(round(cost.getOtherCost()));
        }

        chartData.setLabels(recentMonths);
        chartData.setPurchaseData(purchaseData);
        chartData.setRepairData(repairData);
        chartData.setOtherData(otherData);
    }

    /**
     * 获取费用明细 - 添加分页支持
     */
    private List<CostDetail> getCostDetails(String company, Integer year, Integer month, String statType, int page, int size) {
        List<CostDetail> allDetails = new ArrayList<>();

        try {
            // 获取符合条件的轮胎数据
            List<Tire> tires = getTiresForCostStatistics(company, year, month, statType);

            for (Tire tire : tires) {
                // 采购费用明细
                if (tire.getTirePrice() != null && tire.getTirePrice().doubleValue() > 0) {
                    CostDetail purchaseDetail = new CostDetail();
                    purchaseDetail.setDate(tire.getInstallDate() != null ? tire.getInstallDate().toString() : "未知");
                    purchaseDetail.setCompany(tire.getTransportCompany());
                    purchaseDetail.setPlateNumber(getDisplayPlateNumber(tire));
                    purchaseDetail.setTireNumber(tire.getTireNumber());
                    purchaseDetail.setCostType("采购");
                    purchaseDetail.setAmount(tire.getTirePrice().doubleValue());
                    purchaseDetail.setDescription("轮胎采购 - " + (tire.getTireBrand() != null ? tire.getTireBrand() : "") +
                            " " + (tire.getTireModel() != null ? tire.getTireModel() : ""));
                    allDetails.add(purchaseDetail);
                }

                // 维修费用明细
                if (tire.getRepairCost() != null && tire.getRepairCost().doubleValue() > 0) {
                    CostDetail repairDetail = new CostDetail();
                    repairDetail.setDate(LocalDate.now().toString()); // 实际应该从维修记录获取日期
                    repairDetail.setCompany(tire.getTransportCompany());
                    repairDetail.setPlateNumber(getDisplayPlateNumber(tire));
                    repairDetail.setTireNumber(tire.getTireNumber());
                    repairDetail.setCostType("维修");
                    repairDetail.setAmount(tire.getRepairCost().doubleValue());
                    repairDetail.setDescription("轮胎维修");
                    allDetails.add(repairDetail);
                }

                // 安装费用明细
                if (tire.getInstallCost() != null && tire.getInstallCost().doubleValue() > 0) {
                    CostDetail installDetail = new CostDetail();
                    installDetail.setDate(tire.getInstallDate() != null ? tire.getInstallDate().toString() : "未知");
                    installDetail.setCompany(tire.getTransportCompany());
                    installDetail.setPlateNumber(getDisplayPlateNumber(tire));
                    installDetail.setTireNumber(tire.getTireNumber());
                    installDetail.setCostType("安装");
                    installDetail.setAmount(tire.getInstallCost().doubleValue());
                    installDetail.setDescription("轮胎安装");
                    allDetails.add(installDetail);
                }

                // 调胎费用明细
                if (tire.getSwapCost() != null && tire.getSwapCost().doubleValue() > 0) {
                    CostDetail swapDetail = new CostDetail();
                    swapDetail.setDate(LocalDate.now().toString()); // 实际应该从调胎记录获取日期
                    swapDetail.setCompany(tire.getTransportCompany());
                    swapDetail.setPlateNumber(getDisplayPlateNumber(tire));
                    swapDetail.setTireNumber(tire.getTireNumber());
                    swapDetail.setCostType("调胎");
                    swapDetail.setAmount(tire.getSwapCost().doubleValue());
                    swapDetail.setDescription("轮胎调换");
                    allDetails.add(swapDetail);
                }
            }

            // 分页处理
            int start = (page - 1) * size;
            int end = Math.min(start + size, allDetails.size());
            if (start < allDetails.size()) {
                return allDetails.subList(start, end);
            } else {
                return new ArrayList<>();
            }

        } catch (Exception e) {
            log.error("获取费用明细失败", e);
            // 返回空列表而不是null
            return new ArrayList<>();
        }
    }

    // 辅助类
    class VehicleCost {
        private double purchaseCost = 0.0;
        private double repairCost = 0.0;
        private double otherCost = 0.0;

        // getters and setters
        public double getPurchaseCost() { return purchaseCost; }
        public void setPurchaseCost(double purchaseCost) { this.purchaseCost = purchaseCost; }

        public double getRepairCost() { return repairCost; }
        public void setRepairCost(double repairCost) { this.repairCost = repairCost; }

        public double getOtherCost() { return otherCost; }
        public void setOtherCost(double otherCost) { this.otherCost = otherCost; }
    }

    class CompanyCost {
        private double purchaseCost = 0.0;
        private double repairCost = 0.0;
        private double otherCost = 0.0;

        // getters and setters
        public double getPurchaseCost() { return purchaseCost; }
        public void setPurchaseCost(double purchaseCost) { this.purchaseCost = purchaseCost; }

        public double getRepairCost() { return repairCost; }
        public void setRepairCost(double repairCost) { this.repairCost = repairCost; }

        public double getOtherCost() { return otherCost; }
        public void setOtherCost(double otherCost) { this.otherCost = otherCost; }
    }

    class MonthlyCost {
        private double purchaseCost = 0.0;
        private double repairCost = 0.0;
        private double otherCost = 0.0;

        // getters and setters
        public double getPurchaseCost() { return purchaseCost; }
        public void setPurchaseCost(double purchaseCost) { this.purchaseCost = purchaseCost; }

        public double getRepairCost() { return repairCost; }
        public void setRepairCost(double repairCost) { this.repairCost = repairCost; }

        public double getOtherCost() { return otherCost; }
        public void setOtherCost(double otherCost) { this.otherCost = otherCost; }
    }




    /**
     * 计算费用汇总
     */
    private CostSummary calculateCostSummary(String company, Integer year, Integer month, String statType) {
        CostSummary summary = new CostSummary();

        try {
            // 获取符合条件的轮胎数据
            List<Tire> tires = getTiresForCostStatistics(company, year, month, statType);

            double totalCost = 0.0;
            double purchaseCost = 0.0;
            double repairCost = 0.0;
            double otherCost = 0.0;

            for (Tire tire : tires) {
                // 采购费用
                if (tire.getTirePrice() != null) {
                    purchaseCost += tire.getTirePrice().doubleValue();
                }

                // 维修费用
                if (tire.getRepairCost() != null) {
                    repairCost += tire.getRepairCost().doubleValue();
                }

                // 其他费用（安装费 + 调胎费）
                if (tire.getInstallCost() != null) {
                    otherCost += tire.getInstallCost().doubleValue();
                }
                if (tire.getSwapCost() != null) {
                    otherCost += tire.getSwapCost().doubleValue();
                }
            }

            totalCost = purchaseCost + repairCost + otherCost;

            summary.setTotalCost(round(totalCost));
            summary.setPurchaseCost(round(purchaseCost));
            summary.setRepairCost(round(repairCost));
            summary.setOtherCost(round(otherCost));

        } catch (Exception e) {
            log.error("计算费用汇总失败", e);
            // 设置默认值
            summary.setTotalCost(0.0);
            summary.setPurchaseCost(0.0);
            summary.setRepairCost(0.0);
            summary.setOtherCost(0.0);
        }

        return summary;
    }

    /**
     * 构建图表数据
     */
    private ChartData buildChartData(String company, Integer year, Integer month, String statType) {
        ChartData chartData = new ChartData();

        try {
            // 根据统计类型构建不同的标签和数据
            if ("yearly".equals(statType)) {
                // 年度统计 - 显示12个月
                chartData.setLabels(Arrays.asList("1月", "2月", "3月", "4月", "5月", "6月",
                        "7月", "8月", "9月", "10月", "11月", "12月"));
            } else {
                // 月度统计或单车结算 - 显示最近6个月
                List<String> recentMonths = getRecentMonths(6);
                chartData.setLabels(recentMonths);
            }

            // 模拟数据 - 实际项目中应该根据时间范围查询真实数据
            chartData.setPurchaseData(Arrays.asList(2000.0, 1500.0, 1800.0, 2200.0, 1300.0, 1200.0));
            chartData.setRepairData(Arrays.asList(500.0, 300.0, 400.0, 600.0, 700.0, 500.0));
            chartData.setOtherData(Arrays.asList(200.0, 150.0, 180.0, 220.0, 130.0, 120.0));

        } catch (Exception e) {
            log.error("构建图表数据失败", e);
            // 设置默认值
            chartData.setLabels(Arrays.asList("1月", "2月", "3月", "4月", "5月", "6月"));
            chartData.setPurchaseData(Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
            chartData.setRepairData(Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
            chartData.setOtherData(Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
        }

        return chartData;
    }

    /**
     * 获取费用明细
     */
    private List<CostDetail> getCostDetails(String company, Integer year, Integer month, String statType) {
        List<CostDetail> details = new ArrayList<>();

        try {
            // 获取符合条件的轮胎数据
            List<Tire> tires = getTiresForCostStatistics(company, year, month, statType);

            for (Tire tire : tires) {
                // 采购费用明细
                if (tire.getTirePrice() != null && tire.getTirePrice().doubleValue() > 0) {
                    CostDetail purchaseDetail = new CostDetail();
                    purchaseDetail.setDate(tire.getInstallDate() != null ? tire.getInstallDate().toString() : "未知");
                    purchaseDetail.setCompany(tire.getTransportCompany());
                    purchaseDetail.setPlateNumber(getDisplayPlateNumber(tire));
                    purchaseDetail.setTireNumber(tire.getTireNumber());
                    purchaseDetail.setCostType("采购");
                    purchaseDetail.setAmount(tire.getTirePrice().doubleValue());
                    purchaseDetail.setDescription("轮胎采购 - " + (tire.getTireBrand() != null ? tire.getTireBrand() : "") +
                            " " + (tire.getTireModel() != null ? tire.getTireModel() : ""));
                    details.add(purchaseDetail);
                }

                // 维修费用明细
                if (tire.getRepairCost() != null && tire.getRepairCost().doubleValue() > 0) {
                    CostDetail repairDetail = new CostDetail();
                    repairDetail.setDate(LocalDate.now().toString()); // 实际应该从维修记录获取日期
                    repairDetail.setCompany(tire.getTransportCompany());
                    repairDetail.setPlateNumber(getDisplayPlateNumber(tire));
                    repairDetail.setTireNumber(tire.getTireNumber());
                    repairDetail.setCostType("维修");
                    repairDetail.setAmount(tire.getRepairCost().doubleValue());
                    repairDetail.setDescription("轮胎维修");
                    details.add(repairDetail);
                }

                // 安装费用明细
                if (tire.getInstallCost() != null && tire.getInstallCost().doubleValue() > 0) {
                    CostDetail installDetail = new CostDetail();
                    installDetail.setDate(tire.getInstallDate() != null ? tire.getInstallDate().toString() : "未知");
                    installDetail.setCompany(tire.getTransportCompany());
                    installDetail.setPlateNumber(getDisplayPlateNumber(tire));
                    installDetail.setTireNumber(tire.getTireNumber());
                    installDetail.setCostType("安装");
                    installDetail.setAmount(tire.getInstallCost().doubleValue());
                    installDetail.setDescription("轮胎安装");
                    details.add(installDetail);
                }

                // 调胎费用明细
                if (tire.getSwapCost() != null && tire.getSwapCost().doubleValue() > 0) {
                    CostDetail swapDetail = new CostDetail();
                    swapDetail.setDate(LocalDate.now().toString()); // 实际应该从调胎记录获取日期
                    swapDetail.setCompany(tire.getTransportCompany());
                    swapDetail.setPlateNumber(getDisplayPlateNumber(tire));
                    swapDetail.setTireNumber(tire.getTireNumber());
                    swapDetail.setCostType("调胎");
                    swapDetail.setAmount(tire.getSwapCost().doubleValue());
                    swapDetail.setDescription("轮胎调换");
                    details.add(swapDetail);
                }
            }

        } catch (Exception e) {
            log.error("获取费用明细失败", e);
            // 返回空列表而不是null
        }

        return details;
    }

    /**
     * 获取用于费用统计的轮胎数据
     */
    private List<Tire> getTiresForCostStatistics(String company, Integer year, Integer month, String statType) {
        List<Tire> allTires = tireRepository.findAll();

        return allTires.stream()
                .filter(tire -> company == null || company.isEmpty() ||
                        (tire.getTransportCompany() != null && tire.getTransportCompany().equals(company)))
                .filter(tire -> {
                    if (year == null) return true;

                    LocalDate installDate = tire.getInstallDate();
                    if (installDate == null) return false;

                    if (month == null) {
                        // 只按年份筛选
                        return installDate.getYear() == year;
                    } else {
                        // 按年份和月份筛选
                        return installDate.getYear() == year && installDate.getMonthValue() == month;
                    }
                })
                .collect(Collectors.toList());
    }

    /**
     * 获取显示的车牌号
     */
    private String getDisplayPlateNumber(Tire tire) {
        if (tire.getVehiclePlateNumber() != null && tire.getTrailerPlateNumber() != null) {
            return tire.getVehiclePlateNumber() + "/" + tire.getTrailerPlateNumber();
        } else if (tire.getVehiclePlateNumber() != null) {
            return tire.getVehiclePlateNumber();
        } else if (tire.getTrailerPlateNumber() != null) {
            return tire.getTrailerPlateNumber();
        } else {
            return "未安装";
        }
    }

    /**
     * 获取最近几个月的月份列表
     */
    private List<String> getRecentMonths(int count) {
        List<String> months = new ArrayList<>();
        LocalDate now = LocalDate.now();

        for (int i = count - 1; i >= 0; i--) {
            LocalDate month = now.minusMonths(i);
            months.add(month.getMonthValue() + "月");
        }

        return months;
    }

    /**
     * 四舍五入到两位小数
     */
    private double round(double value) {
        return Math.round(value * 100.0) / 100.0;
    }

    /**
     * 导出费用统计报表
     */
    public void exportCostStatistics(String company, Integer year, Integer month, String statType, HttpServletResponse response) {
        try {
            // 获取统计数据（这里获取所有数据，不分页）
            CostStatisticsResponse costData = getCostStatistics(company, year, month, statType, 1, Integer.MAX_VALUE);

            // 设置响应头
            setupResponseHeaders(response, company, year, month, statType);

            // 生成Excel报表
            generateExcelReport(costData, company, year, month, statType, response.getOutputStream());

            log.info("导出费用统计报表成功: company={}, year={}, month={}, statType={}", company, year, month, statType);

        } catch (Exception e) {
            log.error("导出费用统计报表失败", e);
            throw new RuntimeException("导出失败: " + e.getMessage(), e);
        }
    }

    /**
     * 设置响应头
     */
    private void setupResponseHeaders(HttpServletResponse response, String company, Integer year, Integer month, String statType) {
        try {
            // 生成文件名
            String fileName = generateFileName(company, year, month, statType);

            // 设置响应类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");

            // 设置文件名（处理中文文件名）
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);

            // 禁用缓存
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setDateHeader("Expires", 0);

        } catch (UnsupportedEncodingException e) {
            log.error("设置响应头失败", e);
            // 使用默认文件名
            response.setHeader("Content-Disposition", "attachment; filename=cost_statistics.xlsx");
        }
    }

    /**
     * 生成文件名
     */
    private String generateFileName(String company, Integer year, Integer month, String statType) {
        StringBuilder fileName = new StringBuilder("费用统计报表");

        // 添加公司信息
        if (company != null && !company.isEmpty()) {
            fileName.append("_").append(company);
        }

        // 添加时间信息
        if (year != null) {
            fileName.append("_").append(year).append("年");
            if (month != null) {
                fileName.append(month).append("月");
            }
        }

        // 添加统计类型
        if (statType != null) {
            switch (statType) {
                case "monthly":
                    fileName.append("_月度统计");
                    break;
                case "yearly":
                    fileName.append("_年度统计");
                    break;
                case "vehicle":
                    fileName.append("_单车结算");
                    break;
                case "company":
                    fileName.append("_公司统计");
                    break;
                default:
                    fileName.append("_统计报表");
            }
        }

        fileName.append(".xlsx");
        return fileName.toString();
    }

    /**
     * 生成Excel报表
     */
    private void generateExcelReport(CostStatisticsResponse costData, String company, Integer year, Integer month, String statType, OutputStream outputStream) {
        // 创建工作簿
        try (XSSFWorkbook workbook = new XSSFWorkbook()) {

            // 创建样式
            Map<String, XSSFCellStyle> styles = createStyles(workbook);

            // 1. 创建汇总表
            createSummarySheet(workbook, styles, costData.getSummary(), company, year, month, statType);

            // 2. 创建图表数据表
            createChartDataSheet(workbook, styles, costData.getChartData(), statType);

            // 3. 创建费用明细表
            createDetailsSheet(workbook, styles, costData.getDetails());

            // 写入输出流
            workbook.write(outputStream);

        } catch (Exception e) {
            throw new RuntimeException("生成Excel报表失败: " + e.getMessage(), e);
        }
    }

    /**
     * 创建单元格样式
     */
    private Map<String, XSSFCellStyle> createStyles(XSSFWorkbook workbook) {
        Map<String, XSSFCellStyle> styles = new HashMap<>();

        // 标题样式
        XSSFCellStyle titleStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontHeightInPoints((short) 16);
        titleStyle.setFont(titleFont);
        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        styles.put("title", titleStyle);

        // 表头样式
        XSSFCellStyle headerStyle = workbook.createCellStyle();
        XSSFFont headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerFont.setFontHeightInPoints((short) 12);
        headerStyle.setFont(headerFont);
        headerStyle.setFillForegroundColor(new XSSFColor(new java.awt.Color(217, 217, 217), null));
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headerStyle.setBorderBottom(BorderStyle.THIN);
        headerStyle.setBorderTop(BorderStyle.THIN);
        headerStyle.setBorderLeft(BorderStyle.THIN);
        headerStyle.setBorderRight(BorderStyle.THIN);
        headerStyle.setAlignment(HorizontalAlignment.CENTER);
        styles.put("header", headerStyle);

        // 数据样式
        XSSFCellStyle dataStyle = workbook.createCellStyle();
        dataStyle.setBorderBottom(BorderStyle.THIN);
        dataStyle.setBorderTop(BorderStyle.THIN);
        dataStyle.setBorderLeft(BorderStyle.THIN);
        dataStyle.setBorderRight(BorderStyle.THIN);
        styles.put("data", dataStyle);

        // 金额样式
        XSSFCellStyle currencyStyle = workbook.createCellStyle();
        currencyStyle.setBorderBottom(BorderStyle.THIN);
        currencyStyle.setBorderTop(BorderStyle.THIN);
        currencyStyle.setBorderLeft(BorderStyle.THIN);
        currencyStyle.setBorderRight(BorderStyle.THIN);
        currencyStyle.setDataFormat(workbook.createDataFormat().getFormat("¥#,##0.00"));
        styles.put("currency", currencyStyle);

        // 汇总样式
        XSSFCellStyle summaryStyle = workbook.createCellStyle();
        XSSFFont summaryFont = workbook.createFont();
        summaryFont.setBold(true);
        summaryFont.setFontHeightInPoints((short) 12);
        summaryStyle.setFont(summaryFont);
        summaryStyle.setFillForegroundColor(new XSSFColor(new java.awt.Color(221, 235, 247), null));
        summaryStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        summaryStyle.setBorderBottom(BorderStyle.THIN);
        summaryStyle.setBorderTop(BorderStyle.THIN);
        summaryStyle.setBorderLeft(BorderStyle.THIN);
        summaryStyle.setBorderRight(BorderStyle.THIN);
        styles.put("summary", summaryStyle);

        return styles;
    }

    /**
     * 创建汇总表
     */
    private void createSummarySheet(XSSFWorkbook workbook, Map<String, XSSFCellStyle> styles,
                                    CostSummary summary, String company, Integer year, Integer month, String statType) {
        XSSFSheet sheet = workbook.createSheet("费用汇总");

        int rowNum = 0;

        // 标题行
        XSSFRow titleRow = sheet.createRow(rowNum++);
        XSSFCell titleCell = titleRow.createCell(0);
        titleCell.setCellValue("费用统计报表");
        titleCell.setCellStyle(styles.get("title"));
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 3));

        // 统计条件行
        XSSFRow conditionRow = sheet.createRow(rowNum++);
        createConditionRow(conditionRow, company, year, month, statType, styles);
        sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 3));

        rowNum++; // 空行

        // 汇总表头
        XSSFRow headerRow = sheet.createRow(rowNum++);
        String[] headers = {"费用类型", "金额(元)", "占比", "说明"};
        for (int i = 0; i < headers.length; i++) {
            XSSFCell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(styles.get("header"));
        }

        // 汇总数据
        double totalCost = summary.getTotalCost();
        String[][] summaryData = {
                {"总费用", String.valueOf(totalCost), "100%", "所有费用总和"},
                {"采购费用", String.valueOf(summary.getPurchaseCost()),
                        calculatePercentage(summary.getPurchaseCost(), totalCost), "轮胎采购相关费用"},
                {"维修费用", String.valueOf(summary.getRepairCost()),
                        calculatePercentage(summary.getRepairCost(), totalCost), "轮胎维修相关费用"},
                {"其他费用", String.valueOf(summary.getOtherCost()),
                        calculatePercentage(summary.getOtherCost(), totalCost), "安装、调胎等其他费用"}
        };

        for (String[] data : summaryData) {
            XSSFRow row = sheet.createRow(rowNum++);
            for (int i = 0; i < data.length; i++) {
                XSSFCell cell = row.createCell(i);
                if (i == 1) { // 金额列
                    cell.setCellValue(Double.parseDouble(data[i]));
                    cell.setCellStyle(styles.get("currency"));
                } else {
                    cell.setCellValue(data[i]);
                    cell.setCellStyle(styles.get("summary"));
                }
            }
        }

        // 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }
    }

    /**
     * 创建统计条件行
     */
    private void createConditionRow(XSSFRow row, String company, Integer year, Integer month, String statType, Map<String, XSSFCellStyle> styles) {
        StringBuilder condition = new StringBuilder("统计条件: ");

        if (company != null && !company.isEmpty()) {
            condition.append("公司=").append(company).append("; ");
        }

        if (year != null) {
            condition.append("年份=").append(year).append("年");
            if (month != null) {
                condition.append(month).append("月");
            }
            condition.append("; ");
        }

        if (statType != null) {
            switch (statType) {
                case "monthly":
                    condition.append("统计类型=月度统计");
                    break;
                case "yearly":
                    condition.append("统计类型=年度统计");
                    break;
                case "vehicle":
                    condition.append("统计类型=单车结算");
                    break;
                case "company":
                    condition.append("统计类型=公司统计");
                    break;
                default:
                    condition.append("统计类型=未知");
            }
        }

        XSSFCell cell = row.createCell(0);
        cell.setCellValue(condition.toString());
        cell.setCellStyle(styles.get("data"));
    }

    /**
     * 计算百分比
     */
    private String calculatePercentage(double value, double total) {
        if (total == 0) {
            return "0%";
        }
        double percentage = (value / total) * 100;
        return String.format("%.2f%%", percentage);
    }

    /**
     * 创建图表数据表
     */
    private void createChartDataSheet(XSSFWorkbook workbook, Map<String, XSSFCellStyle> styles, ChartData chartData, String statType) {
        XSSFSheet sheet = workbook.createSheet("图表数据");

        int rowNum = 0;

        // 标题行
        XSSFRow titleRow = sheet.createRow(rowNum++);
        XSSFCell titleCell = titleRow.createCell(0);
        titleCell.setCellValue("图表数据");
        titleCell.setCellStyle(styles.get("title"));

        // 根据统计类型确定表头
        String xAxisTitle = getXAxisTitle(statType);
        String[] headers = {xAxisTitle, "采购费用", "维修费用", "其他费用", "总费用"};

        // 表头行
        XSSFRow headerRow = sheet.createRow(rowNum++);
        for (int i = 0; i < headers.length; i++) {
            XSSFCell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(styles.get("header"));
        }

        // 数据行
        List<String> labels = chartData.getLabels();
        List<Double> purchaseData = chartData.getPurchaseData();
        List<Double> repairData = chartData.getRepairData();
        List<Double> otherData = chartData.getOtherData();

        for (int i = 0; i < labels.size(); i++) {
            XSSFRow row = sheet.createRow(rowNum++);

            // 标签
            XSSFCell labelCell = row.createCell(0);
            labelCell.setCellValue(labels.get(i));
            labelCell.setCellStyle(styles.get("data"));

            // 采购费用
            XSSFCell purchaseCell = row.createCell(1);
            purchaseCell.setCellValue(i < purchaseData.size() ? purchaseData.get(i) : 0);
            purchaseCell.setCellStyle(styles.get("currency"));

            // 维修费用
            XSSFCell repairCell = row.createCell(2);
            repairCell.setCellValue(i < repairData.size() ? repairData.get(i) : 0);
            repairCell.setCellStyle(styles.get("currency"));

            // 其他费用
            XSSFCell otherCell = row.createCell(3);
            otherCell.setCellValue(i < otherData.size() ? otherData.get(i) : 0);
            otherCell.setCellStyle(styles.get("currency"));

            // 总费用
            XSSFCell totalCell = row.createCell(4);
            double total = (i < purchaseData.size() ? purchaseData.get(i) : 0) +
                    (i < repairData.size() ? repairData.get(i) : 0) +
                    (i < otherData.size() ? otherData.get(i) : 0);
            totalCell.setCellValue(total);
            totalCell.setCellStyle(styles.get("currency"));
        }

        // 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }
    }

    /**
     * 获取X轴标题
     */
    private String getXAxisTitle(String statType) {
        switch (statType) {
            case "vehicle":
                return "车牌号";
            case "company":
                return "运输公司";
            case "yearly":
                return "月份";
            case "monthly":
            default:
                return "时间";
        }
    }

    /**
     * 创建费用明细表
     */
    private void createDetailsSheet(XSSFWorkbook workbook, Map<String, XSSFCellStyle> styles, List<CostDetail> details) {
        XSSFSheet sheet = workbook.createSheet("费用明细");

        int rowNum = 0;

        // 标题行
        XSSFRow titleRow = sheet.createRow(rowNum++);
        XSSFCell titleCell = titleRow.createCell(0);
        titleCell.setCellValue("费用明细");
        titleCell.setCellStyle(styles.get("title"));
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 7));

        // 表头行
        XSSFRow headerRow = sheet.createRow(rowNum++);
        String[] headers = {"日期", "运输公司", "车牌号", "轮胎号", "费用类型", "金额(元)", "说明", "操作人"};
        for (int i = 0; i < headers.length; i++) {
            XSSFCell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(styles.get("header"));
        }

        // 数据行
        for (CostDetail detail : details) {
            XSSFRow row = sheet.createRow(rowNum++);

            // 日期
            XSSFCell dateCell = row.createCell(0);
            dateCell.setCellValue(detail.getDate());
            dateCell.setCellStyle(styles.get("data"));

            // 运输公司
            XSSFCell companyCell = row.createCell(1);
            companyCell.setCellValue(detail.getCompany());
            companyCell.setCellStyle(styles.get("data"));

            // 车牌号
            XSSFCell plateCell = row.createCell(2);
            plateCell.setCellValue(detail.getPlateNumber());
            plateCell.setCellStyle(styles.get("data"));

            // 轮胎号
            XSSFCell tireCell = row.createCell(3);
            tireCell.setCellValue(detail.getTireNumber());
            tireCell.setCellStyle(styles.get("data"));

            // 费用类型
            XSSFCell typeCell = row.createCell(4);
            typeCell.setCellValue(detail.getCostType());
            typeCell.setCellStyle(styles.get("data"));

            // 金额
            XSSFCell amountCell = row.createCell(5);
            amountCell.setCellValue(detail.getAmount());
            amountCell.setCellStyle(styles.get("currency"));

            // 说明
            XSSFCell descCell = row.createCell(6);
            descCell.setCellValue(detail.getDescription());
            descCell.setCellStyle(styles.get("data"));

            // 操作人
            XSSFCell operatorCell = row.createCell(7);
            operatorCell.setCellValue(detail.getOperator());
            operatorCell.setCellStyle(styles.get("data"));
        }

        // 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }
    }








    @Autowired
    private TireRepository tireRepository;

    // 预定义的轮胎位置坐标（6轴挂车）
    private static final Map<Integer, Map<String, Map<String, Integer>>> POSITION_COORDINATES = createPositionCoordinates();

    private static Map<Integer, Map<String, Map<String, Integer>>> createPositionCoordinates() {
        Map<Integer, Map<String, Map<String, Integer>>> coordinates = new HashMap<>();

        // 1轴坐标
        coordinates.put(1, Map.of(
                "左外", Map.of("x", 150, "y", 240),
                "左内", Map.of("x", 250, "y", 240),
                "右内", Map.of("x", 350, "y", 240),
                "右外", Map.of("x", 450, "y", 240)
        ));

        // 2轴坐标
        coordinates.put(2, Map.of(
                "左外", Map.of("x", 150, "y", 310),
                "左内", Map.of("x", 250, "y", 310),
                "右内", Map.of("x", 350, "y", 310),
                "右外", Map.of("x", 450, "y", 310)
        ));

        // 3轴坐标
        coordinates.put(3, Map.of(
                "左外", Map.of("x", 150, "y", 380),
                "左内", Map.of("x", 250, "y", 380),
                "右内", Map.of("x", 350, "y", 380),
                "右外", Map.of("x", 450, "y", 380)
        ));

        // 4轴坐标
        coordinates.put(4, Map.of(
                "左外", Map.of("x", 150, "y", 450),
                "左内", Map.of("x", 250, "y", 450),
                "右内", Map.of("x", 350, "y", 450),
                "右外", Map.of("x", 450, "y", 450)
        ));

        // 5轴坐标
        coordinates.put(5, Map.of(
                "左外", Map.of("x", 150, "y", 520),
                "左内", Map.of("x", 250, "y", 520),
                "右内", Map.of("x", 350, "y", 520),
                "右外", Map.of("x", 450, "y", 520)
        ));

        // 6轴坐标
        coordinates.put(6, Map.of(
                "左外", Map.of("x", 150, "y", 590),
                "左内", Map.of("x", 250, "y", 590),
                "右内", Map.of("x", 350, "y", 590),
                "右外", Map.of("x", 450, "y", 590)
        ));

        return coordinates;
    }

    // 保存单个轮胎信息
    public Tire saveTire(Tire tire) {
        return tireRepository.save(tire);
    }

    /**
     * 获取挂车轮胎可视化数据（修复版，包含ID字段）
     */
    public TireVisualizationDTO getTrailerVisualization(String trailerPlateNumber) {
        System.out.println("=== 开始查询拖车可视化数据 ===");
        System.out.println("查询的车牌号: '" + trailerPlateNumber + "'");

        // 使用多种方式查询轮胎
        List<Tire> tires = new ArrayList<>();

        // 方法1：拖车车牌查询
        List<Tire> trailerTires = tireRepository.findByTrailerPlateNumber(trailerPlateNumber);
        System.out.println("拖车车牌查询结果: " + trailerTires.size());
        tires.addAll(trailerTires);

        // 方法2：车辆车牌查询
        List<Tire> vehicleTires = tireRepository.findByVehiclePlateNumber(trailerPlateNumber);
        System.out.println("车辆车牌查询结果: " + vehicleTires.size());
        tires.addAll(vehicleTires);

        // 去重（基于轮胎号）
        Map<String, Tire> uniqueTires = new HashMap<>();
        for (Tire tire : tires) {
            if (tire.getTireNumber() != null) {
                uniqueTires.put(tire.getTireNumber(), tire);
            }
        }
        tires = new ArrayList<>(uniqueTires.values());

        System.out.println("去重后的轮胎总数: " + tires.size());

        // 打印轮胎详细信息，特别关注轴号和位置
        System.out.println("=== 轮胎详细信息 ===");
        for (Tire tire : tires) {
            System.out.println("轮胎ID: " + tire.getId() +
                    ", 轮胎号: " + tire.getTireNumber() +
                    ", 轴号: " + tire.getAxleNumber() +
                    ", 位置: " + tire.getTirePosition() +
                    ", 完整位置: " + tire.getPosition() +
                    ", 车辆车牌: " + tire.getVehiclePlateNumber() +
                    ", 拖车车牌: " + tire.getTrailerPlateNumber());
        }

        TireVisualizationDTO visualization = new TireVisualizationDTO();
        visualization.setTrailerPlateNumber(trailerPlateNumber);

        List<TirePositionInfo> positionInfos = new ArrayList<>();

        // 为6个轴的所有位置创建信息
        for (int axle = 1; axle <= 6; axle++) {
            String[] positions = {"左外", "左内", "右内", "右外"};

            for (String pos : positions) {
                TirePositionInfo positionInfo = createPositionInfo(axle, pos);

                // 增强的轮胎查找逻辑（传递 positionInfos 参数）
                Tire tire = findTireByPositionEnhanced(tires, axle, pos, positionInfos);
                if (tire != null) {
                    positionInfo.setHasTire(true);
                    positionInfo.setTireInfo(convertToTireInfo(tire));
                    System.out.println("✅ 成功匹配轮胎: ID=" + tire.getId() +
                            ", 编号=" + tire.getTireNumber() +
                            " 到位置: " + axle + "轴" + pos);
                } else {
                    positionInfo.setHasTire(false);
                    positionInfo.setTireInfo(null);
                    System.out.println("❌ 位置 " + axle + "轴" + pos + " 没有匹配的轮胎");
                }

                positionInfos.add(positionInfo);
            }
        }

        visualization.setPositions(positionInfos);

        // 统计结果显示
        long tiresWithPosition = positionInfos.stream().filter(pos -> pos.isHasTire()).count();
        System.out.println("=== 查询完成 ===");
        System.out.println("总位置数: " + positionInfos.size());
        System.out.println("有轮胎的位置数: " + tiresWithPosition);
        System.out.println("无轮胎的位置数: " + (positionInfos.size() - tiresWithPosition));

        return visualization;
    }

    /**
     * 增强的轮胎位置匹配逻辑
     */
    private Tire findTireByPositionEnhanced(List<Tire> tires, int axleNumber, String tirePosition, List<TirePositionInfo> positionInfos) {
        if (tires == null || tires.isEmpty()) {
            return null;
        }

        // 方法1：精确匹配轴号和位置
        for (Tire tire : tires) {
            if (tire.getAxleNumber() != null && tire.getTirePosition() != null) {
                boolean axleMatch = tire.getAxleNumber().equals(axleNumber);
                boolean positionMatch = tire.getTirePosition().trim().equals(tirePosition.trim());

                if (axleMatch && positionMatch) {
                    return tire;
                }
            }
        }

        // 方法2：通过完整位置字段匹配
        String expectedPosition = axleNumber + "轴" + tirePosition;
        for (Tire tire : tires) {
            if (tire.getPosition() != null && tire.getPosition().contains(expectedPosition)) {
                System.out.println("通过完整位置字段匹配成功: " + tire.getPosition());
                return tire;
            }
        }

        // 方法3：模糊匹配（处理可能的格式差异）
        for (Tire tire : tires) {
            if (tire.getAxleNumber() != null && tire.getTirePosition() != null) {
                // 处理位置名称的变体
                boolean positionVariantMatch = isPositionVariantMatch(tire.getTirePosition(), tirePosition);
                if (tire.getAxleNumber().equals(axleNumber) && positionVariantMatch) {
                    System.out.println("通过位置变体匹配成功: " + tire.getTirePosition() + " -> " + tirePosition);
                    return tire;
                }
            }
        }

        // 方法4：如果轮胎没有明确的位置，尝试分配到第一个可用位置
        for (Tire tire : tires) {
            if ((tire.getAxleNumber() == null || tire.getTirePosition() == null) &&
                    !isTireAlreadyAssigned(tires, tire.getTireNumber(), positionInfos)) {
                System.out.println("分配无位置轮胎: " + tire.getTireNumber() + " 到位置: " + axleNumber + "轴" + tirePosition);
                return tire;
            }
        }

        return null;
    }

    /**
     * 检查位置名称的变体匹配
     */
    private boolean isPositionVariantMatch(String actualPosition, String expectedPosition) {
        if (actualPosition == null || expectedPosition == null) {
            return false;
        }

        String actual = actualPosition.trim();
        String expected = expectedPosition.trim();

        // 直接匹配
        if (actual.equals(expected)) {
            return true;
        }

        // 处理常见的位置名称变体
        Map<String, String> variants = new HashMap<>();
        variants.put("左外侧", "左外");
        variants.put("左侧外", "左外");
        variants.put("右外侧", "右外");
        variants.put("右侧外", "右外");
        variants.put("左内侧", "左内");
        variants.put("左侧内", "左内");
        variants.put("右内侧", "右内");
        variants.put("右侧内", "右内");
        variants.put("外侧左", "左外");
        variants.put("外侧右", "右外");
        variants.put("内侧左", "左内");
        variants.put("内侧右", "右内");

        // 检查变体匹配
        String normalizedActual = variants.getOrDefault(actual, actual);
        return normalizedActual.equals(expected);
    }

    /**
     * 检查轮胎是否已经被分配到某个位置
     */
    private boolean isTireAlreadyAssigned(List<Tire> tires, String tireNumber, List<TirePositionInfo> positionInfos) {
        for (TirePositionInfo positionInfo : positionInfos) {
            // 使用 getter 方法而不是直接访问字段
            if (positionInfo.isHasTire() && positionInfo.getTireInfo() != null &&
                    tireNumber.equals(positionInfo.getTireInfo().getTireNumber())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 创建位置信息（不依赖TirePosition枚举）
     */
    private TirePositionInfo createPositionInfo(int axle, String position) {
        TirePositionInfo positionInfo = new TirePositionInfo();
        positionInfo.setPositionKey(axle + "轴" + position);
        positionInfo.setAxleNumber(axle);
        positionInfo.setTirePosition(position);

        // 直接从预定义的坐标映射中获取坐标
        if (POSITION_COORDINATES.containsKey(axle) &&
                POSITION_COORDINATES.get(axle).containsKey(position)) {
            Map<String, Integer> coord = POSITION_COORDINATES.get(axle).get(position);
            positionInfo.setX(coord.get("x"));
            positionInfo.setY(coord.get("y"));
        } else {
            // 默认坐标（应该不会发生）
            positionInfo.setX(0);
            positionInfo.setY(0);
        }

        return positionInfo;
    }

    /**
     * 根据轴数和位置查找轮胎（增强版）
     */
    private Tire findTireByPosition(List<Tire> tires, int axleNumber, String tirePosition) {
        if (tires == null || tires.isEmpty()) {
            return null;
        }

        // 首先尝试精确匹配
        Optional<Tire> exactMatch = tires.stream()
                .filter(t -> t.getAxleNumber() != null &&
                        t.getAxleNumber() == axleNumber &&
                        t.getTirePosition() != null &&
                        t.getTirePosition().equals(tirePosition))
                .findFirst();

        if (exactMatch.isPresent()) {
            return exactMatch.get();
        }

        // 如果精确匹配失败，尝试模糊匹配（处理可能的空格或格式问题）
        return tires.stream()
                .filter(t -> t.getAxleNumber() != null &&
                        t.getAxleNumber() == axleNumber &&
                        t.getTirePosition() != null &&
                        t.getTirePosition().trim().equals(tirePosition.trim()))
                .findFirst()
                .orElse(null);
    }

    /**
     * 将Tire实体转换为TireInfo DTO（简化版，去掉花纹深度）
     */
    private TireInfo convertToTireInfo(Tire tire) {
        TireInfo info = new TireInfo();
        // 关键：设置轮胎ID
        info.setId(tire.getId());
        info.setTireNumber(tire.getTireNumber());
        info.setTireBrand(tire.getTireBrand());
        info.setTireModel(tire.getTireModel());
        info.setTransportCompany(tire.getTransportCompany());
        info.setCurrentMileage(tire.getCurrentMileage());
        info.setInstallDate(tire.getInstallDate());

        // 不再计算花纹深度
        return info;
    }

    /**
     * 根据位置信息获取轮胎
     */
    public Tire getTireByPosition(String trailerPlateNumber, Integer axleNumber, String tirePosition) {
        List<Tire> tires = tireRepository.findByTrailerPlateNumber(trailerPlateNumber);
        return findTireByPosition(tires, axleNumber, tirePosition);
    }

    /**
     * 更新轮胎位置
     */
    @Transactional
    public boolean updateTirePosition(String tireNumber, String trailerPlateNumber,
                                      Integer axleNumber, String tirePosition) {
        Tire tire = tireRepository.findByTireNumber(tireNumber);
        if (tire != null) {
            tire.setTrailerPlateNumber(trailerPlateNumber);
            tire.setAxleNumber(axleNumber);
            tire.setTirePosition(tirePosition);
            if (axleNumber != null && tirePosition != null) {
                tire.setPosition(axleNumber + "轴" + tirePosition);
            }
            tireRepository.save(tire);
            return true;
        }
        return false;
    }

    /**
     * 批量保存轮胎信息 - 修复照片保存问题（增强版）
     */
    @Transactional
    public boolean saveTireBatch(TireBatchDto tireBatchDto) {
        try {
            System.out.println("=== 开始批量保存轮胎（包含照片） ===");
            System.out.println("轮胎数量: " + tireBatchDto.getTires().size());

            List<Tire> savedTires = new ArrayList<>();
            boolean anyPhotosSaved = false;

            // 1. 保存所有轮胎
            for (TireBatchDto.TireInfo tireInfo : tireBatchDto.getTires()) {
                if (tireInfo.getTireNumber() != null && !tireInfo.getTireNumber().trim().isEmpty()) {
                    // 检查轮胎号是否已存在
                    Tire existingTire = tireRepository.findByTireNumber(tireInfo.getTireNumber().trim());
                    if (existingTire != null) {
                        System.out.println("轮胎号已存在，跳过: " + tireInfo.getTireNumber());
                        continue;
                    }

                    // 创建轮胎实体
                    Tire tire = createTireFromDto(tireInfo, tireBatchDto);

                    // 保存轮胎
                    Tire savedTire = tireRepository.save(tire);
                    savedTires.add(savedTire);
                    System.out.println("成功保存轮胎: " + tireInfo.getTireNumber() + ", ID: " + savedTire.getId());

                    // 2. 立即保存照片（在同一个事务中）
                    if (tireInfo.getPhotos() != null && tireInfo.getPhotos().length > 0) {
                        System.out.println("开始为轮胎 " + savedTire.getTireNumber() + " 保存照片，数量: " + tireInfo.getPhotos().length);

                        // 详细检查照片信息
                        for (int i = 0; i < tireInfo.getPhotos().length; i++) {
                            MultipartFile photo = tireInfo.getPhotos()[i];
                            if (photo != null && !photo.isEmpty()) {
                                System.out.println("照片 " + i + ": " + photo.getOriginalFilename() +
                                        ", 大小: " + photo.getSize() + " bytes");
                            } else {
                                System.out.println("照片 " + i + ": 空文件");
                            }
                        }

                        boolean photosSaved = saveTirePhotos(savedTire.getId(), tireInfo.getPhotos());
                        if (photosSaved) {
                            anyPhotosSaved = true;
                            System.out.println("✅ 成功为轮胎 " + savedTire.getTireNumber() + " 保存照片");
                        } else {
                            System.out.println("❌ 为轮胎 " + savedTire.getTireNumber() + " 保存照片失败");
                        }
                    } else {
                        System.out.println("轮胎 " + savedTire.getTireNumber() + " 没有照片需要保存");
                    }
                }
            }

            // 立即刷新并验证
            if (!savedTires.isEmpty()) {
                tireRepository.flush();
                System.out.println("轮胎和照片保存事务已提交");

                // 验证保存结果
                for (Tire tire : savedTires) {
                    boolean exists = tireRepository.existsById(tire.getId());
                    System.out.println("轮胎验证 - ID: " + tire.getId() + ", 数据库中存在: " + exists);
                }
            }

            System.out.println("批量保存完成，成功保存 " + savedTires.size() + " 个轮胎，照片保存状态: " + anyPhotosSaved);
            return !savedTires.isEmpty();

        } catch (Exception e) {
            System.err.println("批量保存轮胎时发生错误: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("保存轮胎失败: " + e.getMessage(), e);
        }
    }

    /**
     * 保存轮胎照片 - 处理 List<MultipartFile>
     */
    private boolean saveTirePhotos(Long tireId, List<MultipartFile> photosList) {
        try {
            System.out.println("=== 开始保存轮胎照片 ===");
            System.out.println("轮胎ID: " + tireId);
            System.out.println("照片数量: " + (photosList != null ? photosList.size() : 0));

            if (photosList != null && !photosList.isEmpty()) {
                for (int i = 0; i < photosList.size(); i++) {
                    MultipartFile photo = photosList.get(i);
                    // 检查单个文件是否为空
                    if (photo != null && !photo.isEmpty()) {
                        System.out.println("照片 " + i + ": " + photo.getOriginalFilename() +
                                ", 大小: " + photo.getSize() + " bytes, " +
                                "内容类型: " + photo.getContentType());
                    } else {
                        System.out.println("照片 " + i + ": 空文件或null");
                    }
                }
            } else {
                System.out.println("照片列表为空或null");
                return false;
            }

            // 将 List 转换为数组，因为 TirePhotoService 需要数组
            MultipartFile[] photosArray = photosList.toArray(new MultipartFile[0]);
            List<TirePhoto> savedPhotos = tirePhotoService.savePhotosInSameTransaction(tireId, photosArray);
            boolean success = savedPhotos != null && !savedPhotos.isEmpty();

            System.out.println("照片保存结果: " + success);
            System.out.println("实际保存的照片数量: " + (savedPhotos != null ? savedPhotos.size() : 0));

            return success;

        } catch (Exception e) {
            System.err.println("保存轮胎照片失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 从 DTO 创建轮胎实体
     */
    private Tire createTireFromDto(TireBatchDto.TireInfo tireInfo, TireBatchDto tireBatchDto) {
        Tire tire = new Tire();
        tire.setTireNumber(tireInfo.getTireNumber().trim());
        tire.setVehiclePlateNumber(tireBatchDto.getVehiclePlateNumber());
        tire.setTrailerPlateNumber(tireBatchDto.getTrailerPlateNumber());
        tire.setTireBrand(tireInfo.getTireBrand());
        tire.setTireModel(tireInfo.getTireModel());
        tire.setInstallDate(tireBatchDto.getInstallDate());
        tire.setInstallMileage(tireBatchDto.getInstallMileage() != null ? tireBatchDto.getInstallMileage() : 0);
        tire.setTirePrice(tireInfo.getTirePrice());
        tire.setInstallCost(tireInfo.getInstallCost());
        tire.setTransportCompany(tireBatchDto.getTransportCompany());
        tire.setAxleNumber(tireInfo.getAxleNumber());
        tire.setTirePosition(tireInfo.getTirePosition());

        // 设置完整位置描述
        if (tireInfo.getAxleNumber() != null && tireInfo.getTirePosition() != null) {
            tire.setPosition(tireInfo.getAxleNumber() + "轴" + tireInfo.getTirePosition());
        }

        return tire;
    }

    /**
     * 保存轮胎照片 - 处理 MultipartFile[]
     */
    private boolean saveTirePhotos(Long tireId, MultipartFile[] photos) {
        try {
            System.out.println("=== 开始保存轮胎照片 ===");
            System.out.println("轮胎ID: " + tireId);
            System.out.println("照片数量: " + (photos != null ? photos.length : 0));

            if (photos != null && photos.length > 0) {
                for (int i = 0; i < photos.length; i++) {
                    MultipartFile photo = photos[i];
                    if (photo != null && !photo.isEmpty()) {
                        System.out.println("照片 " + i + ": " + photo.getOriginalFilename() +
                                ", 大小: " + photo.getSize() + " bytes, " +
                                "内容类型: " + photo.getContentType());
                    } else {
                        System.out.println("照片 " + i + ": 空文件或null");
                    }
                }

                List<TirePhoto> savedPhotos = tirePhotoService.savePhotosInSameTransaction(tireId, photos);
                boolean success = savedPhotos != null && !savedPhotos.isEmpty();

                System.out.println("照片保存结果: " + success);
                System.out.println("实际保存的照片数量: " + (savedPhotos != null ? savedPhotos.size() : 0));
                return success;
            } else {
                System.out.println("没有照片需要保存");
                return false;
            }

        } catch (Exception e) {
            System.err.println("保存轮胎照片失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 保存轮胎并立即提交事务
     */
    @Transactional
    public List<Tire> saveTiresAndCommit(TireBatchDto tireBatchDto) {
        List<Tire> savedTires = new ArrayList<>();

        for (TireBatchDto.TireInfo tireInfo : tireBatchDto.getTires()) {
            if (tireInfo.getTireNumber() != null && !tireInfo.getTireNumber().trim().isEmpty()) {
                // 检查轮胎号是否已存在
                Tire existingTire = tireRepository.findByTireNumber(tireInfo.getTireNumber().trim());
                if (existingTire != null) {
                    System.out.println("轮胎号已存在，跳过: " + tireInfo.getTireNumber());
                    continue;
                }

                Tire tire = new Tire();
                tire.setTireNumber(tireInfo.getTireNumber().trim());
                tire.setVehiclePlateNumber(tireBatchDto.getVehiclePlateNumber());
                tire.setTrailerPlateNumber(tireBatchDto.getTrailerPlateNumber());
                tire.setTireBrand(tireInfo.getTireBrand());
                tire.setTireModel(tireInfo.getTireModel());
                tire.setInstallDate(tireBatchDto.getInstallDate());
                tire.setInstallMileage(tireBatchDto.getInstallMileage() != null ? tireBatchDto.getInstallMileage() : 0);
                tire.setTirePrice(tireInfo.getTirePrice());
                tire.setInstallCost(tireInfo.getInstallCost());
                tire.setTransportCompany(tireBatchDto.getTransportCompany());
                tire.setAxleNumber(tireInfo.getAxleNumber());
                tire.setTirePosition(tireInfo.getTirePosition());

                // 设置完整位置描述
                if (tireInfo.getAxleNumber() != null && tireInfo.getTirePosition() != null) {
                    tire.setPosition(tireInfo.getAxleNumber() + "轴" + tireInfo.getTirePosition());
                }

                // 保存轮胎
                Tire savedTire = tireRepository.save(tire);
                savedTires.add(savedTire);
                System.out.println("成功保存轮胎: " + tireInfo.getTireNumber() + ", ID: " + savedTire.getId());
            }
        }

        // 立即刷新并验证
        if (!savedTires.isEmpty()) {
            tireRepository.flush();
            System.out.println("轮胎保存事务已提交");

            // 验证轮胎确实存在于数据库
            for (Tire tire : savedTires) {
                boolean exists = tireRepository.existsById(tire.getId());
                System.out.println("轮胎验证 - ID: " + tire.getId() + ", 数据库中存在: " + exists);
            }
        }

        return savedTires;
    }

    /**
     * 在新的事务中保存照片
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public boolean savePhotosInNewTransaction(List<Tire> savedTires, TireBatchDto tireBatchDto) {
        boolean anyPhotosSaved = false;

        for (int i = 0; i < tireBatchDto.getTires().size(); i++) {
            TireBatchDto.TireInfo tireInfo = tireBatchDto.getTires().get(i);
            if (tireInfo.getTireNumber() != null && !tireInfo.getTireNumber().trim().isEmpty()) {
                // 找到对应的已保存轮胎
                Tire savedTire = savedTires.stream()
                        .filter(t -> t.getTireNumber().equals(tireInfo.getTireNumber().trim()))
                        .findFirst()
                        .orElse(null);

                if (savedTire != null && tireInfo.getPhotos() != null && tireInfo.getPhotos().length > 0) {
                    try {
                        System.out.println("开始为轮胎 " + savedTire.getTireNumber() + " (ID: " + savedTire.getId() + ") 保存照片");

                        // 在新的事务中再次验证轮胎是否存在
                        boolean tireExists = tireRepository.existsById(savedTire.getId());
                        if (!tireExists) {
                            System.err.println("错误：轮胎在照片保存事务中不存在，ID: " + savedTire.getId());
                            continue;
                        }

                        // 使用 TirePhotoService 保存照片
                        List<TirePhoto> savedPhotos = tirePhotoService.savePhotos(savedTire.getId(), tireInfo.getPhotos());

                        if (!savedPhotos.isEmpty()) {
                            anyPhotosSaved = true;
                            System.out.println("为轮胎 " + savedTire.getTireNumber() + " 保存了 " + savedPhotos.size() + " 张照片到数据库");
                        } else {
                            System.out.println("为轮胎 " + savedTire.getTireNumber() + " 保存照片失败或没有照片需要保存");
                        }

                    } catch (Exception e) {
                        System.err.println("保存轮胎照片失败，但继续处理其他照片: " + e.getMessage());
                        // 不抛出异常，避免影响主要业务逻辑
                    }
                }
            }
        }

        return anyPhotosSaved;
    }






    // 添加调胎记录
    @Transactional
    public Tire addSwapRecord(String tireNumber, String swapRecord, Integer swapMileage, BigDecimal swapCost) {
        Tire tire = tireRepository.findByTireNumber(tireNumber);
        if (tire != null) {
            String currentRecords = tire.getSwapRecords();
            String newRecord = LocalDate.now() + ": " + swapRecord + " (" + swapMileage + "公里) - 费用:" + swapCost + "元\n";

            if (currentRecords == null) {
                tire.setSwapRecords(newRecord);
            } else {
                tire.setSwapRecords(currentRecords + newRecord);
            }

            tire.setSwapMileage(swapMileage);
            if (tire.getSwapCost() == null) {
                tire.setSwapCost(swapCost);
            } else {
                tire.setSwapCost(tire.getSwapCost().add(swapCost));
            }

            // 更新轮胎的当前使用公里数
            if (swapMileage != null && swapMileage > 0) {
                tire.setCurrentMileage(swapMileage);
            }

            return tireRepository.save(tire);
        }
        return null;
    }

    // 重载方法，支持更详细的调胎信息 - 修复版
    @Transactional
    public Tire addSwapRecord(String tireNumber, LocalDate swapDate, Integer swapMileage, BigDecimal swapCost,
                              String fromVehiclePlateNumber, String fromTrailerPlateNumber, Integer fromAxleNumber, String fromTirePosition,
                              String toVehiclePlateNumber, String toTrailerPlateNumber, Integer toAxleNumber, String toTirePosition, String swapNote) {

        Tire tire = tireRepository.findByTireNumber(tireNumber);
        if (tire == null) {
            return null;
        }

        System.out.println("=== 调胎操作调试信息 ===");
        System.out.println("调胎前位置 - 车头: " + tire.getVehiclePlateNumber() + ", 挂车: " + tire.getTrailerPlateNumber() + ", 轴号: " + tire.getAxleNumber() + ", 位置: " + tire.getTirePosition());
        System.out.println("调胎后位置 - 车头: " + toVehiclePlateNumber + ", 挂车: " + toTrailerPlateNumber + ", 轴号: " + toAxleNumber + ", 位置: " + toTirePosition);

        // 构建调胎记录描述
        StringBuilder swapRecordBuilder = new StringBuilder();
        swapRecordBuilder.append("调胎: ");

        // 调胎前位置
        if (fromVehiclePlateNumber != null && !fromVehiclePlateNumber.trim().isEmpty()) {
            swapRecordBuilder.append("从").append(fromVehiclePlateNumber);
            if (fromTrailerPlateNumber != null && !fromTrailerPlateNumber.trim().isEmpty()) {
                swapRecordBuilder.append("/").append(fromTrailerPlateNumber);
            }
            if (fromAxleNumber != null && fromTirePosition != null) {
                swapRecordBuilder.append(" ").append(fromAxleNumber).append("轴").append(fromTirePosition);
            }
        }

        // 调胎后位置 - 修复：正确处理空值
        boolean hasToPosition = false;

        // 车头牌号处理
        if (toVehiclePlateNumber != null) {
            // 即使为空字符串也要更新
            tire.setVehiclePlateNumber(toVehiclePlateNumber.trim().isEmpty() ? null : toVehiclePlateNumber);
            hasToPosition = true;
        }

        // 挂车牌号处理
        if (toTrailerPlateNumber != null) {
            tire.setTrailerPlateNumber(toTrailerPlateNumber.trim().isEmpty() ? null : toTrailerPlateNumber);
            hasToPosition = true;
        }

        // 轴号和位置处理
        if (toAxleNumber != null) {
            tire.setAxleNumber(toAxleNumber);
            hasToPosition = true;
        }

        if (toTirePosition != null) {
            tire.setTirePosition(toTirePosition.trim().isEmpty() ? null : toTirePosition);
            hasToPosition = true;
        }

        // 设置完整位置描述
        if (toAxleNumber != null && toTirePosition != null && !toTirePosition.trim().isEmpty()) {
            tire.setPosition(toAxleNumber + "轴" + toTirePosition);
        } else {
            tire.setPosition(null);
        }

        // 构建调胎记录描述 - 调胎后部分
        if (hasToPosition) {
            swapRecordBuilder.append(" → ");

            boolean hasContent = false;

            // 车头牌号
            if (toVehiclePlateNumber != null && !toVehiclePlateNumber.trim().isEmpty()) {
                swapRecordBuilder.append(toVehiclePlateNumber);
                hasContent = true;
            }

            // 挂车牌号
            if (toTrailerPlateNumber != null && !toTrailerPlateNumber.trim().isEmpty()) {
                if (hasContent) swapRecordBuilder.append("/");
                swapRecordBuilder.append(toTrailerPlateNumber);
                hasContent = true;
            }

            // 轴号和位置
            if (toAxleNumber != null && toTirePosition != null && !toTirePosition.trim().isEmpty()) {
                if (hasContent) swapRecordBuilder.append(" ");
                swapRecordBuilder.append(toAxleNumber).append("轴").append(toTirePosition);
            }
        }

        if (swapNote != null && !swapNote.trim().isEmpty()) {
            swapRecordBuilder.append(" (").append(swapNote).append(")");
        }

        String swapRecord = swapRecordBuilder.toString();
        System.out.println("生成的调胎记录: " + swapRecord);
        System.out.println("更新后轮胎位置 - 车头: " + tire.getVehiclePlateNumber() + ", 挂车: " + tire.getTrailerPlateNumber() + ", 轴号: " + tire.getAxleNumber() + ", 位置: " + tire.getTirePosition());

        // 确保保存轮胎的位置更新
        tireRepository.save(tire);

        // 调用已有的添加记录方法
        return addSwapRecord(tireNumber, swapRecord, swapMileage, swapCost);
    }

    /**
     * 调胎报废方法 - 新增方法
     * 处理调胎过程中轮胎报废的情况
     */
    @Transactional
    public Tire swapAndScrapTire(String tireNumber, LocalDate swapDate, Integer swapMileage, BigDecimal swapCost,
                                 String fromVehiclePlateNumber, String fromTrailerPlateNumber, Integer fromAxleNumber,
                                 String fromTirePosition, String swapNote) {
        Tire tire = tireRepository.findByTireNumber(tireNumber);
        if (tire != null) {
            // 构建调胎报废记录描述
            StringBuilder swapRecordBuilder = new StringBuilder();
            swapRecordBuilder.append("调胎报废: ");

            // 记录调胎前位置
            if (fromVehiclePlateNumber != null && !fromVehiclePlateNumber.trim().isEmpty()) {
                swapRecordBuilder.append("从").append(fromVehiclePlateNumber);
                if (fromTrailerPlateNumber != null && !fromTrailerPlateNumber.trim().isEmpty()) {
                    swapRecordBuilder.append("/").append(fromTrailerPlateNumber);
                }
                if (fromAxleNumber != null && fromTirePosition != null) {
                    swapRecordBuilder.append(" ").append(fromAxleNumber).append("轴").append(fromTirePosition);
                }
            }
            swapRecordBuilder.append(" 报废");

            if (swapNote != null && !swapNote.trim().isEmpty()) {
                swapRecordBuilder.append(" (").append(swapNote).append(")");
            }

            String swapRecord = swapRecordBuilder.toString();

            // 添加调胎记录
            addSwapRecord(tireNumber, swapRecord, swapMileage, swapCost);

            // 标记轮胎为报废
            return scrapTire(tireNumber, swapMileage);
        }
        return null;
    }

    /**
     * 获取轮胎的调胎记录统计
     */
    public SwapRecordStats getSwapRecordStats(String tireNumber) {
        Tire tire = tireRepository.findByTireNumber(tireNumber);
        if (tire == null) {
            return null;
        }

        SwapRecordStats stats = new SwapRecordStats();
        stats.setTireNumber(tireNumber);
        stats.setTotalSwapCost(tire.getSwapCost());

        if (tire.getSwapRecords() != null) {
            String[] records = tire.getSwapRecords().split("\n");
            stats.setSwapCount(records.length);
            stats.setLastSwapMileage(tire.getSwapMileage());

            // 解析最后一条记录获取最后调胎日期
            if (records.length > 0) {
                String lastRecord = records[records.length - 1];
                if (lastRecord.contains(":")) {
                    try {
                        String dateStr = lastRecord.substring(0, lastRecord.indexOf(":"));
                        stats.setLastSwapDate(LocalDate.parse(dateStr));
                    } catch (Exception e) {
                        // 日期解析失败，忽略
                    }
                }
            }
        } else {
            stats.setSwapCount(0);
        }

        return stats;
    }

    /**
     * 获取轮胎使用统计（增强版 - 返回完整信息）
     */
    public TireUsageStats getTireUsageStats(String tireNumber) {
        Tire tire = tireRepository.findByTireNumber(tireNumber);
        if (tire == null) {
            return null;
        }

        TireUsageStats stats = new TireUsageStats();

        // 基本信息
        stats.setTireNumber(tire.getTireNumber());
        stats.setTireBrand(tire.getTireBrand());
        stats.setTireModel(tire.getTireModel());
        stats.setTransportCompany(tire.getTransportCompany());

        // 位置信息
        stats.setCurrentPlateNumber(tire.getVehiclePlateNumber());
        stats.setTrailerPlateNumber(tire.getTrailerPlateNumber());
        stats.setPosition(tire.getPosition());
        stats.setAxleNumber(tire.getAxleNumber());
        stats.setTirePosition(tire.getTirePosition());

        // 安装信息
        stats.setInstallDate(tire.getInstallDate());
        stats.setInstallMileage(tire.getInstallMileage());
        stats.setCurrentMileage(tire.getCurrentMileage());

        // 费用信息
        stats.setTirePrice(tire.getTirePrice());
        stats.setInstallCost(tire.getInstallCost());
        stats.setRepairCost(tire.getRepairCost());
        stats.setSwapCost(tire.getSwapCost());

        // 计算总费用
        BigDecimal totalCost = BigDecimal.ZERO;
        if (tire.getTirePrice() != null) totalCost = totalCost.add(tire.getTirePrice());
        if (tire.getInstallCost() != null) totalCost = totalCost.add(tire.getInstallCost());
        if (tire.getRepairCost() != null) totalCost = totalCost.add(tire.getRepairCost());
        if (tire.getSwapCost() != null) totalCost = totalCost.add(tire.getSwapCost());
        stats.setTotalCost(totalCost);

        // 记录信息
        stats.setRepairRecords(tire.getRepairRecords());
        stats.setSwapRecords(tire.getSwapRecords());

        // 报废信息
        stats.setScrapDate(tire.getScrapDate());
        stats.setScrapMileage(tire.getScrapMileage());

        // 计算使用情况
        if (tire.getScrapDate() != null && tire.getScrapMileage() != null) {
            // 已报废轮胎
            if (tire.getInstallMileage() != null) {
                stats.setUsedMileage(tire.getScrapMileage() - tire.getInstallMileage());
            }
            if (tire.getInstallDate() != null) {
                stats.setUsedDays(java.time.temporal.ChronoUnit.DAYS.between(
                        tire.getInstallDate(), tire.getScrapDate()));
            }
            stats.setStatus("已报废");
        } else {
            // 未报废轮胎，计算当前使用情况
            if (tire.getInstallMileage() != null && tire.getCurrentMileage() != null) {
                stats.setUsedMileage(tire.getCurrentMileage() - tire.getInstallMileage());
            }
            if (tire.getInstallDate() != null) {
                stats.setUsedDays(java.time.temporal.ChronoUnit.DAYS.between(
                        tire.getInstallDate(), LocalDate.now()));
            }
            stats.setStatus("使用中");
        }

        return stats;
    }

    // 根据ID查询轮胎
    public Optional<Tire> getTireById(Long id) {
        return tireRepository.findById(id);
    }

    // 根据轮胎号查询
    public Tire getTireByNumber(String tireNumber) {
        return tireRepository.findByTireNumber(tireNumber);
    }

    // 查询所有轮胎
    public List<Tire> getAllTires() {
        return tireRepository.findAll();
    }

    // 查询未报废轮胎
    public List<Tire> getActiveTires() {
        return tireRepository.findByScrapDateIsNull();
    }

    // 查询已报废轮胎
    public List<Tire> getScrappedTires() {
        return tireRepository.findByScrapDateIsNotNull();
    }

    // 根据车牌号查询轮胎
    public List<Tire> getTiresByPlateNumber(String plateNumber) {
        List<Tire> vehicleTires = tireRepository.findByVehiclePlateNumber(plateNumber);
        List<Tire> trailerTires = tireRepository.findByTrailerPlateNumber(plateNumber);

        vehicleTires.addAll(trailerTires);
        return vehicleTires;
    }

    // 根据运输公司查询
    //public List<Tire> getTiresByTransportCompany(String transportCompany) {
    //    return tireRepository.findByTransportCompany(transportCompany);
    //}

    // 根据轮胎位置查询
    public List<Tire> getTiresByPosition(String position) {
        return tireRepository.findByPosition(position);
    }

    // 查询所有运输公司
    public List<String> getAllTransportCompanies() {
        return tireRepository.findDistinctTransportCompanies();
    }

    // 查询所有轮胎位置
    public List<String> getAllPositions() {
        return tireRepository.findDistinctPositions();
    }

    // 更新轮胎报废信息
    @Transactional
    public Tire scrapTire(String tireNumber, Integer scrapMileage) {
        Tire tire = tireRepository.findByTireNumber(tireNumber);
        if (tire != null) {
            tire.setScrapDate(LocalDate.now());
            tire.setScrapMileage(scrapMileage);

            // 更新当前公里数为报废公里数
            if (scrapMileage != null && scrapMileage > 0) {
                tire.setCurrentMileage(scrapMileage);
            }

            return tireRepository.save(tire);
        }
        return null;
    }

    // 添加修补记录
    @Transactional
    public void addRepairRecord(Tire tire, String repairRecord, Integer repairMileage, BigDecimal repairCost) {
        // 更新修补费用
        BigDecimal currentRepairCost = tire.getRepairCost() != null ? tire.getRepairCost() : BigDecimal.ZERO;
        tire.setRepairCost(currentRepairCost.add(repairCost));

        // 更新修补记录 - 使用 LocalDateTime 格式化
        String currentRepairRecords = tire.getRepairRecords();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        String newRepairRecord = String.format("修补记录（%s）: %s - 公里数: %d - 费用: ￥%.2f\n",
                LocalDateTime.now().format(formatter),
                repairRecord, repairMileage, repairCost);

        if (currentRepairRecords == null) {
            tire.setRepairRecords(newRepairRecord);
        } else {
            tire.setRepairRecords(currentRepairRecords + newRepairRecord);
        }

        tireRepository.save(tire);
    }






    // 删除轮胎
    @Transactional
    public void deleteTire(Long id) {
        tireRepository.deleteById(id);
    }

    // 调胎记录统计内部类
    public static class SwapRecordStats {
        private String tireNumber;
        private Integer swapCount;
        private BigDecimal totalSwapCost;
        private LocalDate lastSwapDate;
        private Integer lastSwapMileage;

        // Getter和Setter
        public String getTireNumber() { return tireNumber; }
        public void setTireNumber(String tireNumber) { this.tireNumber = tireNumber; }

        public Integer getSwapCount() { return swapCount; }
        public void setSwapCount(Integer swapCount) { this.swapCount = swapCount; }

        public BigDecimal getTotalSwapCost() { return totalSwapCost; }
        public void setTotalSwapCost(BigDecimal totalSwapCost) { this.totalSwapCost = totalSwapCost; }

        public LocalDate getLastSwapDate() { return lastSwapDate; }
        public void setLastSwapDate(LocalDate lastSwapDate) { this.lastSwapDate = lastSwapDate; }

        public Integer getLastSwapMileage() { return lastSwapMileage; }
        public void setLastSwapMileage(Integer lastSwapMileage) { this.lastSwapMileage = lastSwapMileage; }
    }

    // 使用统计内部类（增强版）
    public static class TireUsageStats {
        private Tire tire;
        private String tireNumber;
        private String tireBrand;
        private String tireModel;
        private String transportCompany;

        private String currentPlateNumber;
        private String trailerPlateNumber;
        private String position;
        private Integer axleNumber;
        private String tirePosition;

        private LocalDate installDate;
        private Integer installMileage;
        private Integer currentMileage;
        private Integer usedMileage;
        private Long usedDays;
        private String status;

        private BigDecimal tirePrice;
        private BigDecimal installCost;
        private BigDecimal repairCost;
        private BigDecimal swapCost;
        private BigDecimal totalCost;

        private String repairRecords;
        private String swapRecords;

        private LocalDate scrapDate;
        private Integer scrapMileage;

        // Getter和Setter方法
        public Tire getTire() {
            return tire;
        }

        public void setTire(Tire tire) {
            this.tire = tire;
        }
        public String getTireNumber() { return tireNumber; }
        public void setTireNumber(String tireNumber) { this.tireNumber = tireNumber; }

        public String getTireBrand() { return tireBrand; }
        public void setTireBrand(String tireBrand) { this.tireBrand = tireBrand; }

        public String getTireModel() { return tireModel; }
        public void setTireModel(String tireModel) { this.tireModel = tireModel; }

        public String getTransportCompany() { return transportCompany; }
        public void setTransportCompany(String transportCompany) { this.transportCompany = transportCompany; }

        public String getCurrentPlateNumber() { return currentPlateNumber; }
        public void setCurrentPlateNumber(String currentPlateNumber) { this.currentPlateNumber = currentPlateNumber; }

        public String getTrailerPlateNumber() { return trailerPlateNumber; }
        public void setTrailerPlateNumber(String trailerPlateNumber) { this.trailerPlateNumber = trailerPlateNumber; }

        public String getPosition() { return position; }
        public void setPosition(String position) { this.position = position; }

        public Integer getAxleNumber() { return axleNumber; }
        public void setAxleNumber(Integer axleNumber) { this.axleNumber = axleNumber; }

        public String getTirePosition() { return tirePosition; }
        public void setTirePosition(String tirePosition) { this.tirePosition = tirePosition; }

        public LocalDate getInstallDate() { return installDate; }
        public void setInstallDate(LocalDate installDate) { this.installDate = installDate; }

        public Integer getInstallMileage() { return installMileage; }
        public void setInstallMileage(Integer installMileage) { this.installMileage = installMileage; }

        public Integer getCurrentMileage() { return currentMileage; }
        public void setCurrentMileage(Integer currentMileage) { this.currentMileage = currentMileage; }

        public Integer getUsedMileage() { return usedMileage; }
        public void setUsedMileage(Integer usedMileage) { this.usedMileage = usedMileage; }

        public Long getUsedDays() { return usedDays; }
        public void setUsedDays(Long usedDays) { this.usedDays = usedDays; }

        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }

        public BigDecimal getTirePrice() { return tirePrice; }
        public void setTirePrice(BigDecimal tirePrice) { this.tirePrice = tirePrice; }

        public BigDecimal getInstallCost() { return installCost; }
        public void setInstallCost(BigDecimal installCost) { this.installCost = installCost; }

        public BigDecimal getRepairCost() { return repairCost; }
        public void setRepairCost(BigDecimal repairCost) { this.repairCost = repairCost; }

        public BigDecimal getSwapCost() { return swapCost; }
        public void setSwapCost(BigDecimal swapCost) { this.swapCost = swapCost; }

        public BigDecimal getTotalCost() { return totalCost; }
        public void setTotalCost(BigDecimal totalCost) { this.totalCost = totalCost; }

        public String getRepairRecords() { return repairRecords; }
        public void setRepairRecords(String repairRecords) { this.repairRecords = repairRecords; }

        public String getSwapRecords() { return swapRecords; }
        public void setSwapRecords(String swapRecords) { this.swapRecords = swapRecords; }

        public LocalDate getScrapDate() { return scrapDate; }
        public void setScrapDate(LocalDate scrapDate) { this.scrapDate = scrapDate; }

        public Integer getScrapMileage() { return scrapMileage; }
        public void setScrapMileage(Integer scrapMileage) { this.scrapMileage = scrapMileage; }
    }

    /**
     * 获取轮胎统计数据 - 添加车牌号参数
     */
    public Map<String, Object> getTireStatistics(String transportCompany, String vehiclePlateNumber,
                                                 String trailerPlateNumber, LocalDate startDate, LocalDate endDate) {
        Map<String, Object> statistics = new HashMap<>();

        // 获取基础查询条件
        List<Tire> tires = getTiresByCriteria(transportCompany, vehiclePlateNumber, trailerPlateNumber, startDate, endDate);

        // 总轮胎数量
        int totalTires = tires.size();
        statistics.put("totalTires", totalTires);

        // 轮胎总价值
        BigDecimal totalTireValue = tires.stream()
                .filter(tire -> tire.getTirePrice() != null)
                .map(Tire::getTirePrice)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        statistics.put("totalTireValue", totalTireValue);

        // 装胎总费用
        BigDecimal totalInstallCost = tires.stream()
                .filter(tire -> tire.getInstallCost() != null)
                .map(Tire::getInstallCost)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        statistics.put("totalInstallCost", totalInstallCost);

        // 维修总费用
        BigDecimal totalRepairCost = tires.stream()
                .filter(tire -> tire.getRepairCost() != null)
                .map(Tire::getRepairCost)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        statistics.put("totalRepairCost", totalRepairCost);

        // 调胎总费用
        BigDecimal totalSwapCost = tires.stream()
                .filter(tire -> tire.getSwapCost() != null)
                .map(Tire::getSwapCost)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        statistics.put("totalSwapCost", totalSwapCost);

        // 总费用（轮胎价值 + 所有操作费用）
        BigDecimal totalCost = totalTireValue
                .add(totalInstallCost)
                .add(totalRepairCost)
                .add(totalSwapCost);
        statistics.put("totalCost", totalCost);

        // 使用中的轮胎数量
        long activeTires = tires.stream()
                .filter(tire -> tire.getScrapDate() == null)
                .count();
        statistics.put("activeTires", activeTires);

        // 已报废的轮胎数量
        long scrappedTires = tires.stream()
                .filter(tire -> tire.getScrapDate() != null)
                .count();
        statistics.put("scrappedTires", scrappedTires);

        // 有修补记录的轮胎数量
        long repairedTires = tires.stream()
                .filter(tire -> tire.getRepairRecords() != null && !tire.getRepairRecords().isEmpty())
                .count();
        statistics.put("repairedTires", repairedTires);

        return statistics;
    }

    /**
     * 按品牌型号统计轮胎数据 - 添加车牌号参数
     */
    public List<Map<String, Object>> getStatisticsByBrand(String transportCompany, String vehiclePlateNumber,
                                                          String trailerPlateNumber, LocalDate startDate, LocalDate endDate) {
        List<Tire> tires = getTiresByCriteria(transportCompany, vehiclePlateNumber, trailerPlateNumber, startDate, endDate);

        // 按品牌和型号分组
        Map<String, List<Tire>> groupedByBrandModel = tires.stream()
                .filter(tire -> tire.getTireBrand() != null && tire.getTireModel() != null)
                .collect(Collectors.groupingBy(
                        tire -> tire.getTireBrand() + " - " + tire.getTireModel()
                ));

        List<Map<String, Object>> result = new ArrayList<>();

        for (Map.Entry<String, List<Tire>> entry : groupedByBrandModel.entrySet()) {
            String brandModel = entry.getKey();
            List<Tire> brandTires = entry.getValue();

            Map<String, Object> brandStats = new HashMap<>();
            brandStats.put("brandModel", brandModel);
            brandStats.put("count", brandTires.size());

            // 平均价格
            long tiresWithPrice = brandTires.stream().filter(tire -> tire.getTirePrice() != null).count();
            BigDecimal avgPrice = BigDecimal.ZERO;
            if (tiresWithPrice > 0) {
                BigDecimal totalPrice = brandTires.stream()
                        .filter(tire -> tire.getTirePrice() != null)
                        .map(Tire::getTirePrice)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                avgPrice = totalPrice.divide(BigDecimal.valueOf(tiresWithPrice), 2, RoundingMode.HALF_UP);
            }
            brandStats.put("avgPrice", avgPrice);

            // 总价值
            BigDecimal totalValue = brandTires.stream()
                    .filter(tire -> tire.getTirePrice() != null)
                    .map(Tire::getTirePrice)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            brandStats.put("totalValue", totalValue);

            // 使用中数量
            long activeCount = brandTires.stream()
                    .filter(tire -> tire.getScrapDate() == null)
                    .count();
            brandStats.put("activeCount", activeCount);

            // 报废数量
            long scrappedCount = brandTires.stream()
                    .filter(tire -> tire.getScrapDate() != null)
                    .count();
            brandStats.put("scrappedCount", scrappedCount);

            result.add(brandStats);
        }

        // 按总价值降序排序
        result.sort((a, b) -> {
            BigDecimal valueA = (BigDecimal) a.get("totalValue");
            BigDecimal valueB = (BigDecimal) b.get("totalValue");
            return valueB.compareTo(valueA);
        });

        return result;
    }

    /**
     * 辅助方法：根据条件筛选轮胎 - 添加车牌号参数
     */
    private List<Tire> getTiresByCriteria(String transportCompany, String vehiclePlateNumber,
                                          String trailerPlateNumber, LocalDate startDate, LocalDate endDate) {
        List<Tire> allTires = tireRepository.findAll();

        return allTires.stream()
                .filter(tire -> transportCompany == null || transportCompany.isEmpty() ||
                        (tire.getTransportCompany() != null &&
                                transportCompany.equals(tire.getTransportCompany())))
                .filter(tire -> vehiclePlateNumber == null || vehiclePlateNumber.isEmpty() ||
                        (tire.getVehiclePlateNumber() != null &&
                                tire.getVehiclePlateNumber().contains(vehiclePlateNumber)))
                .filter(tire -> trailerPlateNumber == null || trailerPlateNumber.isEmpty() ||
                        (tire.getTrailerPlateNumber() != null &&
                                tire.getTrailerPlateNumber().contains(trailerPlateNumber)))
                .filter(tire -> {
                    if (startDate == null && endDate == null) {
                        return true;
                    }
                    LocalDate installDate = tire.getInstallDate();
                    if (installDate == null) {
                        return false;
                    }
                    boolean afterStart = startDate == null || !installDate.isBefore(startDate);
                    boolean beforeEnd = endDate == null || !installDate.isAfter(endDate);
                    return afterStart && beforeEnd;
                })
                .collect(Collectors.toList());
    }

    /**
     * 重载方法：保持向后兼容性
     */
    public Map<String, Object> getTireStatistics(String transportCompany, LocalDate startDate, LocalDate endDate) {
        return getTireStatistics(transportCompany, null, null, startDate, endDate);
    }

    /**
     * 重载方法：保持向后兼容性
     */
    public List<Map<String, Object>> getStatisticsByBrand(String transportCompany, LocalDate startDate, LocalDate endDate) {
        return getStatisticsByBrand(transportCompany, null, null, startDate, endDate);
    }

    /**
     * 更新轮胎基本信息
     */
    @Transactional
    public void updateTireBasicInfo(Tire updatedTire) {
        Tire existingTire = tireRepository.findById(updatedTire.getId())
                .orElseThrow(() -> new IllegalArgumentException("无效的轮胎ID: " + updatedTire.getId()));

        // 检查轮胎号是否重复（排除当前轮胎）
        Tire tireWithSameNumber = tireRepository.findByTireNumber(updatedTire.getTireNumber());
        if (tireWithSameNumber != null && !tireWithSameNumber.getId().equals(updatedTire.getId())) {
            throw new IllegalArgumentException("轮胎号已存在: " + updatedTire.getTireNumber());
        }

        // 更新可修改的字段
        existingTire.setTireNumber(updatedTire.getTireNumber());
        existingTire.setTireBrand(updatedTire.getTireBrand());
        existingTire.setTireModel(updatedTire.getTireModel());
        existingTire.setVehiclePlateNumber(updatedTire.getVehiclePlateNumber());
        existingTire.setTrailerPlateNumber(updatedTire.getTrailerPlateNumber());
        existingTire.setTransportCompany(updatedTire.getTransportCompany());
        existingTire.setTirePrice(updatedTire.getTirePrice());
        existingTire.setInstallCost(updatedTire.getInstallCost());
        existingTire.setInstallDate(updatedTire.getInstallDate());
        existingTire.setInstallMileage(updatedTire.getInstallMileage());

        tireRepository.save(existingTire);
    }

    /**
     * 根据ID查找轮胎
     */
    public Optional<Tire> findById(Long id) {
        return tireRepository.findById(id);
    }

    /**
     * 根据轮胎号查找轮胎
     */
    public Optional<Tire> findByTireNumber(String tireNumber) {
        Tire tire = tireRepository.findByTireNumber(tireNumber);
        return Optional.ofNullable(tire);
    }




    // 在 TireService 类中添加以下方法

    /**
     * 模糊查询轮胎使用记录 - 返回匹配的轮胎列表
     */
    public List<TireUsageStats> getTireUsageStatsByPattern(String tirePattern) {
        if (!StringUtils.hasText(tirePattern)) {
            return new ArrayList<>();
        }

        // 使用模糊查询获取匹配的轮胎
        List<Tire> matchedTires = tireRepository.findByTireNumberContaining(tirePattern);

        // 转换为 TireUsageStats 列表
        return matchedTires.stream()
                .map(this::convertToTireUsageStats)
                .collect(Collectors.toList());
    }

    /**
     * 自动补全轮胎编号查询
     */
    public List<String> findTireNumbersByPattern(String pattern) {
        if (!StringUtils.hasText(pattern)) {
            return new ArrayList<>();
        }

        // 限制返回结果数量，避免数据过多
        List<Tire> tires = tireRepository.findByTireNumberContainingOrderByTireNumber(pattern);

        return tires.stream()
                .map(Tire::getTireNumber)
                .distinct()
                .limit(20) // 限制最多返回20条
                .collect(Collectors.toList());
    }

    /**
     * 将 Tire 实体转换为 TireUsageStats（内部使用）
     */
    private TireUsageStats convertToTireUsageStats(Tire tire) {
        if (tire == null) {
            return null;
        }

        TireUsageStats stats = new TireUsageStats();

        // 基本信息
        stats.setTireNumber(tire.getTireNumber());
        stats.setTireBrand(tire.getTireBrand());
        stats.setTireModel(tire.getTireModel());
        stats.setTransportCompany(tire.getTransportCompany());

        // 位置信息
        stats.setCurrentPlateNumber(tire.getVehiclePlateNumber());
        stats.setTrailerPlateNumber(tire.getTrailerPlateNumber());
        stats.setPosition(tire.getPosition());
        stats.setAxleNumber(tire.getAxleNumber());
        stats.setTirePosition(tire.getTirePosition());

        // 安装信息
        stats.setInstallDate(tire.getInstallDate());
        stats.setInstallMileage(tire.getInstallMileage());
        stats.setCurrentMileage(tire.getCurrentMileage());

        // 费用信息
        stats.setTirePrice(tire.getTirePrice());
        stats.setInstallCost(tire.getInstallCost());
        stats.setRepairCost(tire.getRepairCost());
        stats.setSwapCost(tire.getSwapCost());

        // 计算总费用
        BigDecimal totalCost = BigDecimal.ZERO;
        if (tire.getTirePrice() != null) totalCost = totalCost.add(tire.getTirePrice());
        if (tire.getInstallCost() != null) totalCost = totalCost.add(tire.getInstallCost());
        if (tire.getRepairCost() != null) totalCost = totalCost.add(tire.getRepairCost());
        if (tire.getSwapCost() != null) totalCost = totalCost.add(tire.getSwapCost());
        stats.setTotalCost(totalCost);

        // 记录信息
        stats.setRepairRecords(tire.getRepairRecords());
        stats.setSwapRecords(tire.getSwapRecords());

        // 报废信息
        stats.setScrapDate(tire.getScrapDate());
        stats.setScrapMileage(tire.getScrapMileage());

        // 计算使用情况
        if (tire.getScrapDate() != null && tire.getScrapMileage() != null) {
            // 已报废轮胎
            if (tire.getInstallMileage() != null) {
                stats.setUsedMileage(tire.getScrapMileage() - tire.getInstallMileage());
            }
            if (tire.getInstallDate() != null) {
                stats.setUsedDays(java.time.temporal.ChronoUnit.DAYS.between(
                        tire.getInstallDate(), tire.getScrapDate()));
            }
            stats.setStatus("已报废");
        } else {
            // 未报废轮胎，计算当前使用情况
            if (tire.getInstallMileage() != null && tire.getCurrentMileage() != null) {
                stats.setUsedMileage(tire.getCurrentMileage() - tire.getInstallMileage());
            }
            if (tire.getInstallDate() != null) {
                stats.setUsedDays(java.time.temporal.ChronoUnit.DAYS.between(
                        tire.getInstallDate(), LocalDate.now()));
            }
            stats.setStatus("使用中");
        }

        return stats;
    }

    /**
     * 根据轮胎ID获取使用统计（用于详情页面）
     */
    public TireUsageStats getTireUsageStatsById(Long tireId) {
        Optional<Tire> tireOpt = tireRepository.findById(tireId);
        if (tireOpt.isPresent()) {
            return convertToTireUsageStats(tireOpt.get());
        }
        return null;
    }

    /**
     * 自动补全车牌号查询
     */
    public List<String> findPlateNumbersByPattern(String pattern) {
        if (!StringUtils.hasText(pattern)) {
            return new ArrayList<>();
        }

        // 查询车辆车牌号
        List<Tire> vehicleTires = tireRepository.findByVehiclePlateNumberContaining(pattern);
        // 查询拖车车牌号
        List<Tire> trailerTires = tireRepository.findByTrailerPlateNumberContaining(pattern);

        Set<String> plateNumbers = new HashSet<>();

        // 添加车辆车牌号
        vehicleTires.stream()
                .map(Tire::getVehiclePlateNumber)
                .filter(Objects::nonNull)
                .forEach(plateNumbers::add);

        // 添加拖车车牌号
        trailerTires.stream()
                .map(Tire::getTrailerPlateNumber)
                .filter(Objects::nonNull)
                .forEach(plateNumbers::add);

        return plateNumbers.stream()
                .sorted()
                .limit(20) // 限制最多返回20条
                .collect(Collectors.toList());
    }



    public List<Tire> searchTires(String tireNumber, String plateNumber, String transportCompany, String status) {
        List<Tire> allTires = tireRepository.findAll();

        return allTires.stream()
                .filter(tire -> tireNumber == null || tireNumber.isEmpty() ||
                        (tire.getTireNumber() != null && tire.getTireNumber().contains(tireNumber)))
                .filter(tire -> plateNumber == null || plateNumber.isEmpty() ||
                        (tire.getVehiclePlateNumber() != null && tire.getVehiclePlateNumber().contains(plateNumber)) ||
                        (tire.getTrailerPlateNumber() != null && tire.getTrailerPlateNumber().contains(plateNumber)))
                .filter(tire -> transportCompany == null || transportCompany.isEmpty() ||
                        (tire.getTransportCompany() != null && tire.getTransportCompany().equals(transportCompany)))
                .filter(tire -> {
                    if (status == null || status.isEmpty()) {
                        return true;
                    }
                    if ("active".equals(status)) {
                        return tire.getScrapDate() == null;
                    } else if ("scrapped".equals(status)) {
                        return tire.getScrapDate() != null;
                    }
                    return true;
                })
                .collect(Collectors.toList());
    }



    // 在 TireService 类中添加以下方法

    /**
     * 根据车辆车牌号查询轮胎（考虑用户权限）
     */
    public List<Tire> getTiresByVehicle(String vehiclePlateNumber) {
        if (vehiclePlateNumber == null || vehiclePlateNumber.trim().isEmpty()) {
            return new ArrayList<>();
        }

        List<Tire> vehicleTires = tireRepository.findByVehiclePlateNumber(vehiclePlateNumber);
        List<Tire> trailerTires = tireRepository.findByTrailerPlateNumber(vehiclePlateNumber);

        // 合并结果并去重
        Set<Tire> uniqueTires = new HashSet<>();
        uniqueTires.addAll(vehicleTires);
        uniqueTires.addAll(trailerTires);

        return new ArrayList<>(uniqueTires);
    }

    /**
     * 根据运输公司查询轮胎（考虑用户权限）
     */
    public List<Tire> getTiresByTransportCompany(String transportCompany) {
        if (transportCompany == null || transportCompany.trim().isEmpty()) {
            return new ArrayList<>();
        }
        return tireRepository.findByTransportCompany(transportCompany);
    }

    /**
     * 根据位置和车辆查询轮胎
     */
    public List<Tire> getTiresByPositionAndVehicle(String position, String vehiclePlateNumber) {
        if (position == null || vehiclePlateNumber == null) {
            return new ArrayList<>();
        }

        List<Tire> allTires = getTiresByVehicle(vehiclePlateNumber);
        return allTires.stream()
                .filter(tire -> position.equals(tire.getPosition()) ||
                        position.equals(tire.getTirePosition()))
                .collect(Collectors.toList());
    }

    /**
     * 根据位置和运输公司查询轮胎
     */
    public List<Tire> getTiresByPositionAndCompany(String position, String transportCompany) {
        if (position == null || transportCompany == null) {
            return new ArrayList<>();
        }

        List<Tire> companyTires = getTiresByTransportCompany(transportCompany);
        return companyTires.stream()
                .filter(tire -> position.equals(tire.getPosition()) ||
                        position.equals(tire.getTirePosition()))
                .collect(Collectors.toList());
    }

    /**
     * 根据拖车车牌号查询轮胎
     */
    public List<Tire> getTiresByTrailerPlateNumber(String trailerPlateNumber) {
        if (trailerPlateNumber == null || trailerPlateNumber.trim().isEmpty()) {
            return new ArrayList<>();
        }
        return tireRepository.findByTrailerPlateNumber(trailerPlateNumber);
    }

    /**
     * 根据用户角色过滤的轮胎号自动补全查询
     */
    public List<String> findTireNumbersByPattern(String term, User currentUser) {
        if (!StringUtils.hasText(term)) {
            return new ArrayList<>();
        }

        List<Tire> tires;

        // 根据用户角色获取不同的轮胎列表
        switch (currentUser.getRole()) {
            case DRIVER:
                tires = getTiresByVehicle(currentUser.getVehiclePlateNumber());
                break;
            case COMPANY:
                tires = getTiresByTransportCompany(currentUser.getTransportCompany());
                break;
            case ADMIN:
                tires = getAllTires();
                break;
            default:
                tires = new ArrayList<>();
        }

        // 过滤并返回轮胎号列表
        return tires.stream()
                .filter(tire -> tire.getTireNumber() != null &&
                        tire.getTireNumber().toLowerCase().contains(term.toLowerCase()))
                .map(Tire::getTireNumber)
                .distinct()
                .limit(20) // 限制最多返回20条
                .collect(Collectors.toList());
    }

    /**
     * 根据用户角色过滤的车牌号自动补全查询
     */
    public List<String> findPlateNumbersByPattern(String term, User currentUser) {
        if (!StringUtils.hasText(term)) {
            return new ArrayList<>();
        }

        List<Tire> tires;

        // 根据用户角色获取不同的轮胎列表
        switch (currentUser.getRole()) {
            case DRIVER:
                tires = getTiresByVehicle(currentUser.getVehiclePlateNumber());
                break;
            case COMPANY:
                tires = getTiresByTransportCompany(currentUser.getTransportCompany());
                break;
            case ADMIN:
                tires = getAllTires();
                break;
            default:
                tires = new ArrayList<>();
        }

        Set<String> plateNumbers = new HashSet<>();

        // 添加车辆车牌号
        tires.stream()
                .map(Tire::getVehiclePlateNumber)
                .filter(Objects::nonNull)
                .filter(plate -> plate.toLowerCase().contains(term.toLowerCase()))
                .forEach(plateNumbers::add);

        // 添加拖车车牌号
        tires.stream()
                .map(Tire::getTrailerPlateNumber)
                .filter(Objects::nonNull)
                .filter(plate -> plate.toLowerCase().contains(term.toLowerCase()))
                .forEach(plateNumbers::add);

        return plateNumbers.stream()
                .sorted()
                .limit(20) // 限制最多返回20条
                .collect(Collectors.toList());
    }

    /**
     * 根据用户角色过滤的轮胎搜索
     */
    public List<Tire> searchTires(String tireNumber, String plateNumber, String company, String status, User currentUser) {
        List<Tire> allTires;

        // 根据用户角色获取基础轮胎列表
        switch (currentUser.getRole()) {
            case DRIVER:
                // 司机只能看到自己车辆的轮胎（包括车头和挂车）
                allTires = getTiresByVehicle(currentUser.getVehiclePlateNumber());
                log.info("司机 {} 查询到 {} 条基础轮胎记录", currentUser.getUsername(), allTires.size());
                break;
            case COMPANY:
                // 公司只能看到自己公司的轮胎
                allTires = getTiresByTransportCompany(currentUser.getTransportCompany());
                log.info("公司 {} 查询到 {} 条基础轮胎记录", currentUser.getUsername(), allTires.size());
                break;
            case ADMIN:
                // 管理员可以看到所有轮胎
                allTires = getAllTires();
                log.info("管理员查询到 {} 条基础轮胎记录", allTires.size());
                break;
            default:
                allTires = new ArrayList<>();
                log.warn("未知用户角色: {}", currentUser.getRole());
        }

        // 在已经权限过滤的数据基础上进行搜索过滤
        List<Tire> filteredTires = allTires.stream()
                .filter(tire -> tireNumber == null || tireNumber.isEmpty() ||
                        (tire.getTireNumber() != null && tire.getTireNumber().contains(tireNumber)))
                .filter(tire -> plateNumber == null || plateNumber.isEmpty() ||
                        (tire.getVehiclePlateNumber() != null && tire.getVehiclePlateNumber().contains(plateNumber)) ||
                        (tire.getTrailerPlateNumber() != null && tire.getTrailerPlateNumber().contains(plateNumber)))
                .filter(tire -> company == null || company.isEmpty() ||
                        (tire.getTransportCompany() != null && tire.getTransportCompany().equals(company)))
                .filter(tire -> {
                    if (status == null || status.isEmpty()) {
                        return true;
                    }
                    if ("active".equals(status)) {
                        return tire.getScrapDate() == null;
                    } else if ("scrapped".equals(status)) {
                        return tire.getScrapDate() != null;
                    }
                    return true;
                })
                .collect(Collectors.toList());

        log.info("过滤后得到 {} 条轮胎记录", filteredTires.size());
        return filteredTires;
    }




    // 在 TireService 类中添加以下方法

    /**
     * 获取所有车牌号
     */
    public List<String> getAllPlateNumbers() {
        return tireRepository.findAll().stream()
                .flatMap(tire -> {
                    List<String> plates = new ArrayList<>();
                    if (tire.getVehiclePlateNumber() != null && !tire.getVehiclePlateNumber().isEmpty()) {
                        plates.add(tire.getVehiclePlateNumber());
                    }
                    if (tire.getTrailerPlateNumber() != null && !tire.getTrailerPlateNumber().isEmpty()) {
                        plates.add(tire.getTrailerPlateNumber());
                    }
                    return plates.stream();
                })
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * 根据运输公司获取车牌号
     */
    public List<String> getPlateNumbersByCompany(String transportCompany) {
        return tireRepository.findByTransportCompany(transportCompany).stream()
                .flatMap(tire -> {
                    List<String> plates = new ArrayList<>();
                    if (tire.getVehiclePlateNumber() != null && !tire.getVehiclePlateNumber().isEmpty()) {
                        plates.add(tire.getVehiclePlateNumber());
                    }
                    if (tire.getTrailerPlateNumber() != null && !tire.getTrailerPlateNumber().isEmpty()) {
                        plates.add(tire.getTrailerPlateNumber());
                    }
                    return plates.stream();
                })
                .distinct()
                .collect(Collectors.toList());
    }

    // 在 TireService 类中添加以下方法

    /**
     * 获取最新结算记录（支持用户权限过滤）
     */
    public List<SettlementRecord> getLatestSettlementRecords(int limit, User currentUser) {
        try {
            log.info("获取用户 {} 的最新 {} 条结算记录", currentUser.getUsername(), limit);

            List<SettlementRecord> allRecords;

            // 根据用户角色获取不同的记录
            switch (currentUser.getRole()) {
                case ADMIN:
                    // 管理员可以查看所有记录
                    Pageable pageable = PageRequest.of(0, limit, Sort.by(Sort.Direction.DESC, "settlementDate"));
                    allRecords = settlementRecordRepository.findAllByOrderBySettlementDateDesc(pageable);
                    break;
                case COMPANY:
                    // 公司用户只能查看自己公司的记录
                    allRecords = settlementRecordRepository.findByTransportCompanyOrderBySettlementDateDesc(
                            currentUser.getTransportCompany(), PageRequest.of(0, limit));
                    break;
                case DRIVER:
                    // 司机用户只能查看自己车辆相关的记录
                    allRecords = settlementRecordRepository.findByPlateNumberOrderBySettlementDateDesc(
                            currentUser.getVehiclePlateNumber(), PageRequest.of(0, limit));
                    break;
                default:
                    allRecords = new ArrayList<>();
            }

            return allRecords;

        } catch (Exception e) {
            log.error("获取最新结算记录失败", e);
            // 降级方案：获取所有记录后手动排序和限制
            List<SettlementRecord> allRecords = getAllSettlementRecordsForUser(currentUser);
            allRecords.sort((r1, r2) -> {
                if (r1.getSettlementDate() == null && r2.getSettlementDate() == null) return 0;
                if (r1.getSettlementDate() == null) return 1;
                if (r2.getSettlementDate() == null) return -1;
                return r2.getSettlementDate().compareTo(r1.getSettlementDate());
            });

            if (allRecords.size() > limit) {
                return allRecords.subList(0, limit);
            }
            return allRecords;
        }
    }

    /**
     * 根据条件搜索结算记录（支持用户权限过滤）
     */
    public List<SettlementRecord> searchSettlementRecords(String plateNumber, String transportCompany,
                                                          LocalDate startDate, LocalDate endDate, User currentUser) {
        List<SettlementRecord> records;

        // 根据用户角色处理查询参数
        String finalTransportCompany = transportCompany;
        String finalPlateNumber = plateNumber;

        // 对于非管理员用户，限制查询范围
        if (currentUser.getRole() != User.UserRole.ADMIN) {
            if (currentUser.getRole() == User.UserRole.COMPANY) {
                // COMPANY用户只能查看自己公司的记录
                finalTransportCompany = currentUser.getTransportCompany();
            } else if (currentUser.getRole() == User.UserRole.DRIVER) {
                // DRIVER用户只能查看自己车辆相关的记录
                finalPlateNumber = currentUser.getVehiclePlateNumber();
            }
        }

        // 执行查询
        if (StringUtils.hasText(finalPlateNumber)) {
            records = settlementRecordRepository.findByPlateNumberContainingIgnoreCase(finalPlateNumber);
        } else if (StringUtils.hasText(finalTransportCompany)) {
            records = settlementRecordRepository.findByTransportCompany(finalTransportCompany);
        } else if (startDate != null && endDate != null) {
            records = settlementRecordRepository.findBySettlementDateBetween(startDate, endDate);
        } else {
            records = getAllSettlementRecordsForUser(currentUser);
        }

        // 进一步根据用户角色过滤结果
        return filterSettlementRecordsByUser(records, currentUser);
    }

    /**
     * 获取结算记录的车牌号自动补全列表（支持用户权限过滤）
     */
    public List<String> getSettlementPlateNumberSuggestions(String keyword, User currentUser) {
        List<String> allSuggestions;

        // 根据用户角色获取不同的建议列表
        switch (currentUser.getRole()) {
            case ADMIN:
                allSuggestions = settlementRecordRepository.findDistinctPlateNumbers(keyword);
                break;
            case COMPANY:
                // 公司用户只能看到自己公司的车牌号
                allSuggestions = settlementRecordRepository.findDistinctPlateNumbersByCompany(keyword, currentUser.getTransportCompany());
                break;
            case DRIVER:
                // 司机用户只能看到自己的车牌号
                List<String> driverSuggestions = new ArrayList<>();
                if (currentUser.getVehiclePlateNumber() != null &&
                        currentUser.getVehiclePlateNumber().toLowerCase().contains(keyword.toLowerCase())) {
                    driverSuggestions.add(currentUser.getVehiclePlateNumber());
                }
                allSuggestions = driverSuggestions;
                break;
            default:
                allSuggestions = new ArrayList<>();
        }

        return allSuggestions;
    }

    /**
     * 获取结算记录统计信息（支持用户权限过滤）
     */
    public Map<String, Object> getSettlementStatistics(LocalDate startDate, LocalDate endDate, User currentUser) {
        List<SettlementRecord> records;

        // 根据用户角色获取记录
        if (startDate != null && endDate != null) {
            records = getSettlementRecordsByDateRangeForUser(startDate, endDate, currentUser);
        } else {
            records = getAllSettlementRecordsForUser(currentUser);
        }

        Map<String, Object> statistics = new HashMap<>();

        // 总记录数
        statistics.put("totalRecords", records.size());

        // 总金额
        double totalAmount = records.stream()
                .mapToDouble(SettlementRecord::getTotalCost)
                .sum();
        statistics.put("totalAmount", totalAmount);

        // 按服务类型统计
        Map<String, Double> serviceTypeStats = new HashMap<>();
        for (SettlementRecord record : records) {
            if (record.getItems() != null) {
                for (SettlementItem item : record.getItems()) {
                    String serviceType = item.getServiceType();
                    double amount = (item.getTireCost() != null ? item.getTireCost() : 0) +
                            (item.getServiceCost() != null ? item.getServiceCost() : 0);
                    serviceTypeStats.merge(serviceType, amount, Double::sum);
                }
            }
        }
        statistics.put("serviceTypeStats", serviceTypeStats);

        // 按运输公司统计（只对管理员显示）
        if (currentUser.getRole() == User.UserRole.ADMIN) {
            Map<String, Double> companyStats = new HashMap<>();
            for (SettlementRecord record : records) {
                String company = record.getTransportCompany();
                if (company == null) {
                    company = "未知公司";
                }
                companyStats.merge(company, record.getTotalCost(), Double::sum);
            }
            statistics.put("companyStats", companyStats);
        }

        return statistics;
    }

    /**
     * 获取用户有权限访问的运输公司列表
     */
    public List<String> getAccessibleTransportCompanies(User currentUser) {
        switch (currentUser.getRole()) {
            case ADMIN:
                // 管理员可以访问所有运输公司
                return settlementRecordRepository.findDistinctTransportCompanies();
            case COMPANY:
                // 公司用户只能访问自己的运输公司
                List<String> companies = new ArrayList<>();
                if (currentUser.getTransportCompany() != null) {
                    companies.add(currentUser.getTransportCompany());
                }
                return companies;
            case DRIVER:
                // 司机用户不能按公司过滤
                return new ArrayList<>();
            default:
                return new ArrayList<>();
        }
    }

    /**
     * 根据用户角色获取所有结算记录
     */
    private List<SettlementRecord> getAllSettlementRecordsForUser(User currentUser) {
        switch (currentUser.getRole()) {
            case ADMIN:
                return settlementRecordRepository.findAllOrderByCreateTimeDesc();
            case COMPANY:
                return settlementRecordRepository.findByTransportCompany(currentUser.getTransportCompany());
            case DRIVER:
                return settlementRecordRepository.findByPlateNumber(currentUser.getVehiclePlateNumber());
            default:
                return new ArrayList<>();
        }
    }

    /**
     * 根据日期范围获取结算记录（用户权限过滤）
     */
    private List<SettlementRecord> getSettlementRecordsByDateRangeForUser(LocalDate startDate, LocalDate endDate, User currentUser) {
        switch (currentUser.getRole()) {
            case ADMIN:
                return settlementRecordRepository.findBySettlementDateBetween(startDate, endDate);
            case COMPANY:
                return settlementRecordRepository.findByTransportCompanyAndSettlementDateBetween(
                        currentUser.getTransportCompany(), startDate, endDate);
            case DRIVER:
                return settlementRecordRepository.findByPlateNumberAndSettlementDateBetween(
                        currentUser.getVehiclePlateNumber(), startDate, endDate);
            default:
                return new ArrayList<>();
        }
    }

    /**
     * 根据用户角色过滤结算记录
     */
    private List<SettlementRecord> filterSettlementRecordsByUser(List<SettlementRecord> records, User currentUser) {
        return records.stream()
                .filter(record -> hasAccessToSettlementRecord(currentUser, record))
                .collect(Collectors.toList());
    }

    /**
     * 检查用户是否有权限访问结算记录
     */
    private boolean hasAccessToSettlementRecord(User user, SettlementRecord record) {
        if (user == null || record == null) return false;

        switch (user.getRole()) {
            case ADMIN:
                return true;
            case COMPANY:
                return user.getTransportCompany() != null &&
                        user.getTransportCompany().equals(record.getTransportCompany());
            case DRIVER:
                // DRIVER只能查看自己车辆相关的记录
                return user.getVehiclePlateNumber() != null &&
                        user.getVehiclePlateNumber().equals(record.getPlateNumber());
            default:
                return false;
        }
    }



}